কীভাবে কেবল দীর্ঘ বিকল্পগুলির সাথে ব্যাশ কমান্ড লাইনে getopt ব্যবহার করবেন?


13

getoptবাশ কমান্ড লাইনে একটি কমান্ড রয়েছে। getoptসংক্ষিপ্ত বিকল্পগুলির সাথে ব্যবহার করা getopt -o axby "$@"যেতে পারে (যেমন ) এবং সংক্ষিপ্ত এবং দীর্ঘ উভয় বিকল্পের সাথে ব্যবহার করা যেতে পারে (যেমন getopt -o axby -l long-key -- "$@") তবে এখন আমার কেবল দীর্ঘ বিকল্প প্রয়োজন (যেমন সংক্ষিপ্ত বিকল্পগুলি মোটেই বিদ্যমান নেই) তবে কমান্ডটি getopt -l long-key -- "$@"নেই পার্স --long-keyঅপশনটি সঠিকভাবে। সুতরাং আমি কীভাবে কেবল দীর্ঘ বিকল্পগুলির getoptসাথে কমান্ডটি ব্যবহার করতে পারি ? অথবা এটি অসম্ভব বা এটি কমান্ডের একটি বাগ মাত্র ?getopt


আপনি অভ্যন্তরীণ জন্য ট্যাগ getopts, কিন্তু আপনি /usr/bin/getoptকমান্ড ব্যবহার করছেন ।
অ্যান্থন

@ অ্যান্টন দুঃখিত, আমি ভুল ট্যাগটি ব্যবহার করেছি, তবে অন্য ট্যাগ যুক্ত করার মতো যথেষ্ট সুনাম আমি পাইনি, যার জন্য 300 নামকরা প্রয়োজন। তবে, আমি এখনই ভুল ট্যাগটি মুছে ফেলেছি।
ভিক্টর

উত্তর:


15

getoptকোনও সংক্ষিপ্ত বিকল্প না থাকার সাথে পুরোপুরি ঠিক আছে। তবে আপনাকে এটি বলতে হবে যে আপনার কাছে কোনও সংক্ষিপ্ত বিকল্প নেই। এটি সিনট্যাক্সের একটি স্পর্শ - ম্যানুয়াল থেকে:

যদি প্রথম অংশে কোনও -oবা --optionsবিকল্প পাওয়া যায় না, দ্বিতীয় অংশের প্রথম প্যারামিটারটি সংক্ষিপ্ত বিকল্পগুলির স্ট্রিং হিসাবে ব্যবহৃত হয়।

কি আপনার পরীক্ষার ঘটছে করছে: getopt -l long-key -- --long-key fooএকইরূপে --long-keyঅপশনের তালিকা হিসাবে -egklnoyএবং fooএকমাত্র আর্গুমেন্ট হিসাবে। ব্যবহার

getopt -o '' -l long-key -- "$@"

যেমন

$ getopt -l long-key -o '' -- --long-key foo
 --long-key -- 'foo'
$ getopt -l long-key -o '' -- --long-key --not-recognized -n foo
getopt: unrecognized option '--not-recognized'
getopt: invalid option -- 'n'
 --long-key -- 'foo'

এর ওপি এর মিক্সিং কি getoptsএবং getoptআপনার উত্তর করার জন্য সংক্রমিত? আপনি মন্তব্য দিয়ে শুরু করেন getoptsতবে কেবল উল্লেখ করুন getopt
অ্যান্থন

@ অ্যানথন আমার সমস্ত উত্তর getoptজিএনইউ কোর্টিলস থেকে প্রাপ্ত প্রোগ্রাম সম্পর্কে যা প্রশ্নটিই এটি। আমি যে লেখাটি ঠিক করেছি তা স্থির করেছি getopts। ধন্যবাদ। getoptsএমনকি দীর্ঘ বিকল্পগুলিও করে না, সুতরাং এর কোনওটির জন্যই প্রযোজ্য হবে না getopts
গিলস

ওপিতে মূলত getoptsট্যাগটি ছিল । আমি আপনার উত্তরটি পরিবর্তন করতে চাইনি, কারণ আপনি সাধারণত যা লিখছেন তা আমার চেয়ে আপনি বেশি জানেন :-)
অ্যান্থন

আমি এটি বের করার চেষ্টা করে প্রায় এক ঘন্টা হারিয়েছি। আপনি আমাকে কয়েকটা অযথা কফি সিপস সরিয়ে রেখেছেন। ধন্যবাদ ... এই কফিটি এখন আরও ভাল ব্যবহার করতে দিন। ☕️
ডিএমএম

1

ডুনো সম্পর্কে getoptতবে getoptsঅন্তর্নির্মিতগুলি কেবল এই জাতীয় দীর্ঘ বিকল্পগুলি হ্যান্ডেল করতে ব্যবহৃত হতে পারে:

while getopts :-: o
do  case "$o$OPTARG" in
(-longopt1) process ;;
(-longopt2) process ;;
esac; done

অবশ্যই, যেমনটি রয়েছে, যদি দীর্ঘ-বিকল্পগুলির মধ্যে যুক্তি থাকার কথা মনে হয় তবে এটি কাজ করে না। এটি করা যেতে পারে, তবে, আমি যেমন কাজ শিখেছি তাই। আমি প্রাথমিকভাবে এখানে এখানে অন্তর্ভুক্ত করার সময় আমি বুঝতে পেরেছিলাম যে দীর্ঘ-বিকল্পগুলির জন্য এর খুব বেশি উপযোগিতা নেই। এই ক্ষেত্রে এটি কেবলমাত্র case (match)একক, অনুমানযোগ্য চরিত্র দ্বারা আমার ক্ষেত্রগুলি সংক্ষিপ্ত করছিল । এখন, আমি যা জানি, এটি সংক্ষিপ্ত বিকল্পগুলির জন্য দুর্দান্ত - এটি সবচেয়ে কার্যকর যখন এটি অজানা দৈর্ঘ্যের একটি স্ট্রিংয়ের উপর লুপ করে এবং তার বিকল্প-স্ট্রিং অনুযায়ী একক বাইট নির্বাচন করে। কিন্তু যখন বিকল্প নেই ARG, সেখানে আপনি একটি সঙ্গে কাজ করছি অনেক না for var do case $var inসংমিশ্রণ এটা করতে পারে। আমি মনে করি, এটি সহজ রাখা ভাল।

আমি সন্দেহ করি যে এটিই সত্য, getoptতবে আমি এ সম্পর্কে কোনও দৃty়তার সাথে বলতে যথেষ্ট জানি না don't নিম্নলিখিত আরগ অ্যারে প্রদত্ত, আমি আমার নিজের ছোট্ট আরগ পার্সার প্রদর্শন করব - যা মূলত বিবর্তন / কার্যনির্বাহী সম্পর্কের উপর নির্ভর করে যা আমি প্রশংসা করতে এসেছি aliasএবং $((shell=math))

set -- this is ignored by default --lopt1 -s 'some '\'' 
args' here --ignored   and these are ignored \
--alsoignored andthis --lopt2 'and 

some "`more' --lopt1 and just a few more

এটি আর্গ স্ট্রিং আমি কাজ করব। এখন:

aopts() { env - sh -s -- "$@"
} <<OPTCASE 3<<\OPTSCRIPT
acase() case "\$a" in $(fmt='
        (%s) f=%s; aset "?$(($f)):";;\n'
        for a do case "$a" in (--) break;;
        (--*[!_[:alnum:]]*) continue;;
        (--*) printf "$fmt" "$a" "${a#--}";;
        esac;done;printf "$fmt" '--*' ignored)
        (*) aset "" "\$a";;esac
shift "$((SHIFT$$))"; f=ignored; exec <&3 
OPTCASE
aset()  {  alias "$f=$(($f${1:-=$(($f))+}1))"
        [ -n "${2+?}" ] && alias "${f}_$(($f))=$2"; }
for a do acase; done; alias
#END
OPTSCRIPT

যেটি আপনি এটিকে --ডিলিমিটার দ্বারা পৃথক করে আর্গুমেন্টের এক বা দুটি সেট হস্তান্তর করেন তার উপর নির্ভর করে দুটি ভিন্ন উপায়ে আরগ অ্যারে প্রসেস করে । উভয় ক্ষেত্রেই এটি আরগ অ্যারে প্রক্রিয়াকরণের ক্রমের ক্ষেত্রে প্রযোজ্য।

আপনি যদি এটিকে কল করেন:

: $((SHIFT$$=3)); aopts --lopt1 --lopt2 -- "$@"

ব্যবসায়ের এটির প্রথম acase()ক্রমটি দেখতে দেখতে এটির কাজটি লিখতে হবে :

acase() case "$a" in 
    (--lopt1) f=lopt1; aset "?$(($f)):";;
    (--lopt2) f=lopt2; aset "?$(($f)):";;
    (--*) f=ignored; aset "?$(($f)):";;
    (*) aset "" "$a";;esac

আর পাশে shift 3acase()ফাংশন সংজ্ঞায় কমান্ড-প্রতিস্থাপনটি মূল্যায়ন করা হয় যখন কলিং শেল এখানে ফাংশনটির ইনপুট-নথিগুলি তৈরি করে তবে কলিং শেলটিতে acase()কখনও ডাকা হয় না বা সংজ্ঞায়িত হয় না। এটি অবশ্যই সাব-শেলের মাধ্যমে বলা হয়, এবং অবশ্যই আপনি কমান্ড লাইনে আগ্রহের বিকল্পগুলি গতিশীলভাবে নির্দিষ্ট করতে পারেন।

যদি আপনি এটি একটি আন-সীমাবদ্ধ বিন্যাসের হাতে দেন acase()তবে স্ট্রিং দিয়ে শুরু হওয়া সমস্ত আর্গুমেন্টের জন্য এটি ম্যাচগুলির সাথে সহজেই জনপ্রিয় হয় --

ফাংশনটি কার্যত তার সমস্ত প্রক্রিয়াকরণ সাবসেলের মধ্যে করে - পুনরায় আর্গের প্রতিটি মানকে সহযোগী নাম সহ নির্ধারিত উপাধিতে সংরক্ষণ করে। এটির মাধ্যমে যখন এটি সংরক্ষণ করা প্রতিটি মান মুদ্রণ করে alias- যা পসিক্স-নির্দিষ্ট সমস্ত উদ্ধৃত মানগুলি এমনভাবে মুদ্রণের জন্য নির্দিষ্ট করা হয় যাতে তাদের মানগুলি শেলের সাথে পুনরায় সংযোগ স্থাপন করতে পারে। সুতরাং আমি যখন ...

aopts --lopt1 --lopt2 -- "$@"

এর আউটপুটটি দেখতে এমন দেখাচ্ছে:

...ignored...
lopt1='8'
lopt1_1='-s'
lopt1_2='some '\'' args'
lopt1_3='here'
lopt1_4='and'
lopt1_5='just'
lopt1_6='a'
lopt1_7='few'
lopt1_8='more'
lopt2='1'
lopt2_1='and

some "`more'

এটি আরগ তালিকার মধ্য দিয়ে চলে যাওয়ার সাথে সাথে এটি ম্যাচের জন্য কেস ব্লকের বিরুদ্ধে পরীক্ষা করে। যদি এটি কোনও মিল খুঁজে পায় তবে এটি একটি পতাকা ছুঁড়ে - f=optname। এটি আবার কোনও বৈধ বিকল্প না পাওয়া পর্যন্ত এটি প্রতিটি পতাকাকে বর্তমান পতাকার উপর ভিত্তি করে নির্মিত অ্যারেটিতে যুক্ত করবে। একই বিকল্পটি একাধিকবার নির্দিষ্ট করা হলে ফলাফল যৌগিক হবে এবং ওভাররাইড হবে না। কোনও ক্ষেত্রেই নয় - বা উপেক্ষা করা বিকল্পগুলির পরে কোনও যুক্তি - উপেক্ষা করা অ্যারেতে বরাদ্দ করা হয়েছে ।

শেল দ্বারা স্বয়ংক্রিয়ভাবে শেল-ইনপুট জন্য আউটপুট শেল-নিরাপদ হয় এবং তাই:

eval "$(: $((SHIFT$$=3));aopts --lopt1 --lopt2 -- "$@")"

... পুরোপুরি নিরাপদ থাকা উচিত। যদি এটি কোনও কারণে নিরাপদ না হয় তবে আপনার শেল রক্ষণাবেক্ষণকারীকে সম্ভবত আপনার একটি বাগ রিপোর্ট ফাইল করা উচিত।

এটি প্রতিটি ম্যাচের জন্য দুটি ধরণের উপন্যাসের মান নির্ধারণ করে। প্রথমত, এটি একটি পতাকা সেট করে - এটি কোনও বিকল্পের সাথে মেলে না এমন যুক্তিগুলির আগে রয়েছে কিনা তা ঘটে। --flagআরগ তালিকার যে কোনও ঘটনা ট্রিগার করবে flag=1। এটি যৌগিক হয় না - --flag --flag --flagঠিক পায় flag=1। এই মানটি যদিও বৃদ্ধি করে - কোনও যুক্তি যা এটি অনুসরণ করতে পারে। এটি একটি সূচক কী হিসাবে ব্যবহার করা যেতে পারে। evalউপরের কাজ করার পরে আমি এটি করতে পারি:

printf %s\\n "$lopt1" "$lopt2"

... পেতে ...

8
1

এবং তাই:

for o in lopt1 lopt2
do list= i=0; echo "$o = $(($o))"
        while [ "$((i=$i+1))" -le "$(($o))" ]
        do list="$list $o $i \"\${${o}_$i}\" "
done; eval "printf '%s[%02d] = %s\n' $list";  done

আউটপুট

lopt1 = 8
lopt1[01] = -s
lopt1[02] = some ' args
lopt1[03] = here
lopt1[04] = and
lopt1[05] = just
lopt1[06] = a
lopt1[07] = few
lopt1[08] = more
lopt2 = 1
lopt2[01] = and

some "`more

এবং যেগুলি মেলে না সেগুলির জন্য আমি উপরের ক্ষেত্রটিকে উপেক্ষা করার পরিবর্তে বিকল্পটি for ... inপেতে চাই:

ignored = 10
ignored[01] = this
ignored[02] = is
ignored[03] = ignored
ignored[04] = by
ignored[05] = default
ignored[06] = and
ignored[07] = these
ignored[08] = are
ignored[09] = ignored
ignored[10] = andthis
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.