কমা-বিচ্ছিন্ন মানগুলির জন্য বাশ সমাপ্তি


16

আমি কমা-বিচ্ছিন্ন পরামিতিগুলির তালিকার জন্য সমাপ্তির নিয়ম তৈরি করতে চাই। উদাহরণস্বরূপ আমার কাছে কমান্ড রয়েছে যা সার্ভারের নামের তালিকা অর্জন করে:

myscript -s name1,name2,name3

এই মুহুর্তে আমি নিম্নলিখিত সমাপ্তি লিখতে পরিচালিত করেছি:

_myscript () {
  local cur prev opts

  _get_comp_words_by_ref cur prev

  opts='-s'

  servers='name1 name2 name3'

  if [[ ${cur} == -* ]] ; then
    COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
  else
    case "${prev}" in
      -s)
        if [[ "$cur" == *,* ]]; then
          local realcur prefix
          realcur=${cur##*,}
          prefix=${cur%,*}
          COMPREPLY=( $(compgen -W "${servers}" -P "${prefix}," -- ${realcur}) )
        else
          COMPREPLY=( $(compgen -W "${servers}" -- ${cur}) )
        fi
        ;;
      *)
        # do nothing
        ;;
    esac
  fi
}

তবে এতে কমপক্ষে 2 টি সমস্যা রয়েছে:

  1. বর্তমান মানের জন্য পরামর্শগুলি তাদের উপসর্গের সমস্ত পূর্ববর্তী মানগুলি অন্তর্ভুক্ত করে।
  2. এটি সদৃশ মান বিবেচনা করে না।

এই ধরনের ক্ষেত্রে সবচেয়ে ভাল অনুশীলন কি? হয়তো বাশ-কমপ্লিমেন্টগুলির সিএসভি-তালিকাগুলির জন্য কিছু বান্ডিল ফাংশন রয়েছে?


3
কী সাহায্য করতে পারে তা হ'ল আপনি কমা দ্বারা পৃথক হওয়া মানগুলিকে এই জাতীয় পুনরাবৃত্ত তালিকায় বিভক্ত করতে পারেন: IFS=, LIST=("$VARIABLE")যেখানে AR ভেরিয়েবলটিতে আপনার কমা বিভাজিত মান রয়েছে।
মাইকেল এহরেনরিচ

2
চমৎকার ধারণা @ মিশেল এহরনেরিচ, তবে আপনাকে অবশ্যই উদ্ধৃত করা উচিত নয় $VARIABLE, শব্দ ভাঙ্গা ঘটবে না। শুধু ব্যবহার IFS=, LIST=($VARIABLE)
Gus

উত্তর:


6

আপনার বর্ণিত সমস্যাগুলি সমাধান করার মূলত কোনও উপায় নেই, কারণ ব্যাশ COMPREPLYসরাসরি প্রদর্শনের মধ্যে মানগুলি ব্যবহার করে এবং তারপরে ব্যবহারকারীর পাঠ্য প্রতিস্থাপন করতে পারে - আপনি যা চান তা পেতে প্রথমে আপনাকে সম্ভাব্য সম্পূর্ণগুলি তৈরি করতে হবে (কেবল অতিরিক্ত অতিরিক্ত) বাশ প্রদর্শনের জন্য উপসর্গ ব্যতীত সার্ভারের নাম, তবে যখন ব্যাশ ব্যবহারকারীর পাঠ্যটি দীর্ঘতম অ বিরোধবিরোধী স্ট্রিংয়ের সাথে প্রতিস্থাপন করতে চলেছে তখন আপনার উপস্থাপনার সাথে পাঠ্যটি তৈরি করতে আবার আপনার স্ক্রিপ্টটি কল করতে হবে - এবং ব্যাশ এটির জন্য কোনও সুবিধা নেই।

সর্বোত্তম যেটি আমি সামনে আসতে পেরেছি তা হ'ল COMPREPLYসম্পূর্ণ উপসর্গ ( COMPREPLY=( "${prefix},"$(compgen -W "${servers[@]}" -- ${realcur}) )) সহ কেবলমাত্র প্রথম শব্দটি তৈরি করা উচিত , যাতে যদি কেবলমাত্র একটি সম্ভাব্য সমাপ্তি হয় তবে এটি স্বয়ংক্রিয়ভাবে সঠিকভাবে সম্পন্ন হয়, যখন একাধিক সম্ভাব্য সম্পন্ন হয় এরপরে, বাশ এতক্ষণ যা টাইপ করা হয়েছিল তা সরিয়ে ফেলবে না (কারণ প্রথম শব্দের মধ্যে COMPREPLYপুরো উপসর্গ রয়েছে এবং এটি বর্তমানে টাইপ করা পাঠ্যের সাথে মেলে এবং ব্যবহারকারীর পাঠ্য প্রতিস্থাপনের জন্য ব্যাশ দ্বারা নির্বাচিত হবে) এবং উপসর্গ ব্যতীত বিকল্পগুলি প্রদর্শন করবে - ব্যতীত সেই এক শব্দের জন্য যার মধ্যে ইতিমধ্যে উপসর্গ রয়েছে, সুতরাং আউটপুটটি এর মতো দেখাবে:

$ command -s banana,a
ananas     apricot    banana,apple

"আপেল" সমাপ্তির বিকল্পগুলিতে সর্বশেষে সাজানো হয়েছে কারণ এটি উপসর্গ বহন করে যা "বি" দিয়ে শুরু হয় - খুব বিভ্রান্তিকর। সুতরাং আমি এটি করার পরামর্শ দিচ্ছি না।

সদৃশ সম্পর্কিত - ডুপ্লিকেটগুলি না দেখানোর জন্য আপনাকে কেবল $prefixতার অংশটি (সহজ IFS="," prefix_parts=($prefix):) ভাঙতে হবে এবং তারপরে পুনরাবৃত্তি করতে হবে এবং কেবল $serversইতিমধ্যে তালিকাভুক্ত নয় এমন নামগুলি রেখে যেতে হবে । এটি টাইপ করতে ক্লান্তিকর, তাই আমি এটি এখানে দেখাব না, তবে তুলনামূলকভাবে ক্ষুদ্র তাই আমি নিশ্চিত যে আপনি পরিচালনা করতে পারবেন :-)।

সংক্ষিপ্তসার হিসাবে, আমি মনে করি না যে ইনপুট বিকল্পগুলির জন্য আপনার কমা বিভাজিত মানগুলি ব্যবহার করা উচিত, যদি কমপক্ষে আপনি বাশ আশা করেন যে আপনি সম্পূর্ণরূপে সহায়তা করবেন।

আপনি এটি পছন্দ মতো একটি বিকল্প ফর্ম্যাটকে সমর্থন করতে পারেন: command -s <server> [<server> [..]]এবং তারপরে -sঅপশনটির সাথে সাথে অন্যগুলি ছাড়াও এন্ট্রিগুলি সম্পূর্ণ করার জন্য , আপনি কোনও বিকল্প (ম্যাচের পংক্তির সাথে মেলে ) খুঁজে না $COMP_WORDSপাওয়া $COMP_CWORDপর্যন্ত অ্যারে দিয়ে স্ক্যান করুন -*এবং যদি তার "-s" থাকে তবে আপনাকে সার্ভারের নাম সম্পূর্ণ করতে হবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.