শেল স্ক্রিপ্টগুলিতে নাম যুক্তিগুলি পাস করা


114

শেল স্ক্রিপ্টে নামের প্যারামিটারগুলি পাস করার (প্রাপ্ত) কোনও সহজ উপায় আছে কি?

উদাহরণ স্বরূপ,

my_script -p_out '/some/path' -arg_1 '5'

এবং ভিতরে my_script.shতাদের গ্রহণ করুন:

# I believe this notation does not work, but is there anything close to it?
p_out=$ARGUMENTS['p_out']
arg1=$ARGUMENTS['arg_1']

printf "The Argument p_out is %s" "$p_out"
printf "The Argument arg_1 is %s" "$arg1"

বাশ বা জ্যাশে এটি কি সম্ভব?


2
কটাক্ষপাত আছে docopt - এটা নামে পরামিতি সঙ্গে সাহায্য করে এবং করে ইনপুট বৈধতা খুব
বীট

উত্তর:


34

এর সবচেয়ে নিকটতম বাক্য গঠন:

p_out='/some/path' arg_1='5' my_script

7
এর সাথে সম্পর্কিত, যদি কলিং শেলটিতে -kবিকল্পটি সেট করা থাকে তবে একই প্রভাব থাকবে। (একটি অ্যাসাইনমেন্ট আকারে সমস্ত আর্গুমেন্ট পরিবেশে যুক্ত করা হয়, কমান্ডের পূর্ববর্তী সেই অ্যাসাইনমেন্টগুলি কেবল নয়))my_script p_out='/some/path' arg_1='5'
চিপনার

13
আমি এই বাক্য গঠনটি পছন্দ করতাম, তবে এটির একটি বিগ ক্যাভিয়েট রয়েছে: কমান্ড / ফাংশন এক্সিকিউশন হওয়ার পরেও সেই পরিবর্তনশীলগুলি বর্তমান স্কোপটিতে এখনও সংজ্ঞায়িত করা হবে! উদাহরণস্বরূপ: x=42 echo $x; echo $xপরবর্তী মৃত্যুদন্ড কার্যকর করার অর্থ my_script, যদি p_outবাদ দেওয়া হয় তবে এটি সর্বশেষে পাস করা মানকে আটকে রাখবে !! ( '/some/path')
লুকাস সিমন

@ লুকাশসিমন আপনি কি unsetপ্রথম ফাঁসির পরে এগুলি করতে পারবেন না , পরবর্তী মৃত্যুদন্ড কার্যকর করার আগে তাদের পুনরায় সেট করতে পারেন?
নিকস আলেকজান্দ্রিস

2
@ লুকাশাসিমোন এটি সঠিক নয়। x=42 echo $xএমনকি $xপূর্বে সংজ্ঞায়িত না হলে কিছু আউটপুট দেয় না ।
হাউক লেজিং

আপনি ঠিক বলেছেন হককিজিং, এটিকে সংশোধন করার জন্য ধন্যবাদ
লুকাস সিমন

147

আপনি যদি একক-অক্ষর যুক্তি নামগুলির মধ্যে সীমাবদ্ধ থাকা আপত্তি মনে করেন না my_script -p '/some/path' -a5, তবে ব্যাশে আপনি বিল্ট-ইন ব্যবহার করতে পারেন getopts, যেমন

#!/bin/bash

while getopts ":a:p:" opt; do
  case $opt in
    a) arg_1="$OPTARG"
    ;;
    p) p_out="$OPTARG"
    ;;
    \?) echo "Invalid option -$OPTARG" >&2
    ;;
  esac
done

printf "Argument p_out is %s\n" "$p_out"
printf "Argument arg_1 is %s\n" "$arg_1"

তাহলে আপনি করতে পারেন

$ ./my_script -p '/some/path' -a5
Argument p_out is /some/path
Argument arg_1 is 5

একটি সহায়ক ছোট getopts টিউটোরিয়াল আছে বা আপনি help getoptsশেল প্রম্পটে টাইপ করতে পারেন ।


25
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত
কৌশিক ঘোষ

3
আমি জানি এটি কিছুটা পুরানো, তবে যুক্তিগুলির জন্য কেন কেবল 1 টি চিঠি?
কেভিন

1
আমি এটি বাস্তবায়িত করেছি (তবে iএবং সাথে d)। আমি এটি দিয়ে চালানোর সময় আমি my_script -i asd -d asdতর্কটির জন্য একটি খালি স্ট্রিং পাই d। আমি এটি চালানোর সময় my_script -d asd -i asdআমি উভয় আর্গুমেন্টের জন্য খালি স্ট্রিং পাই।
মিল্কনকুকিজ

3
@ মিল্কনকুকিজ - আমারও একই সমস্যা ছিল - শেষ যুক্তির (আমার ক্ষেত্রে 'ডাব্লু') পরে আমি একটি ':' অন্তর্ভুক্ত করি না। একবার আমি ':' যুক্ত করলে এটি প্রত্যাশা অনুযায়ী কাজ শুরু করে
ডেরেক

37

আমি এটি drupal.org থেকে চুরি করেছি , তবে আপনি এরকম কিছু করতে পারেন:

while [ $# -gt 0 ]; do
  case "$1" in
    --p_out=*)
      p_out="${1#*=}"
      ;;
    --arg_1=*)
      arg_1="${1#*=}"
      ;;
    *)
      printf "***************************\n"
      printf "* Error: Invalid argument.*\n"
      printf "***************************\n"
      exit 1
  esac
  shift
done

একমাত্র সতর্কতা হ'ল আপনাকে সিনট্যাক্সটি ব্যবহার করতে হবে my_script --p_out=/some/path --arg_1=5


7
সতর্কতা প্রয়োজনীয় নয়। :) আপনার নিম্নরূপ শর্ত থাকতে পারে:-c|--condition)
মিল্কনকুকিজ 30'17

28

আমি এই স্ক্রিপ্টটি ব্যবহার করি এবং একটি কবজির মতো কাজ করি:

for ARGUMENT in "$@"
do

    KEY=$(echo $ARGUMENT | cut -f1 -d=)
    VALUE=$(echo $ARGUMENT | cut -f2 -d=)   

    case "$KEY" in
            STEPS)              STEPS=${VALUE} ;;
            REPOSITORY_NAME)    REPOSITORY_NAME=${VALUE} ;;     
            *)   
    esac    


done

echo "STEPS = $STEPS"
echo "REPOSITORY_NAME = $REPOSITORY_NAME"

ব্যবহার

bash my_scripts.sh  STEPS="ABC" REPOSITORY_NAME="stackexchange"

কনসোল ফলাফল:

STEPS = ABC
REPOSITORY_NAME = stackexchange

STEPS এবং REPOSITORY_NAME স্ক্রিপ্টে ব্যবহারের জন্য প্রস্তুত।

আর্গুমেন্টগুলি কী অর্ডারে রয়েছে তা বিবেচ্য নয়।


4
এটি পরিষ্কার এবং এটি গ্রহণযোগ্য উত্তর হওয়া উচিত।
মাইগুয়েলমোরিন

15

সাথে zsh, আপনি ব্যবহার করতে চাই zparseopts:

#! /bin/zsh -
zmodload zsh/zutil
zparseopts -A ARGUMENTS -p_out: -arg_1:

p_out=$ARGUMENTS[--p_out]
arg1=$ARGUMENTS[--arg_1]

printf 'Argument p_out is "%s"\n' "$p_out"
printf 'Argument arg_1 is "%s"\n' "$arg_1"

তবে আপনি স্ক্রিপ্টটি কল করবেন myscript --p_out foo

মনে রাখবেন যে zparseoptsদীর্ঘ বিকল্পগুলি সংক্ষিপ্ত বিবরণ বা --p_out=fooজিএনইউয়ের মতো বাক্য গঠনকে সমর্থন করে না getopt(3)


আপনি কী জানেন যে কেন zparseopts যুক্তিগুলির জন্য মাত্র একটি ড্যাশ ব্যবহার করে যেখানে []এটিতে 2 টি ড্যাশ রয়েছে? এটার কোন মানে নাই!
টিমো

@ টিমো, বিশদগুলির info zsh zparseoptsজন্য দেখুন
স্টাফেন চেজেলাস

9

আমি এই স্ক্রিপ্টটি নিয়ে এসেছি

while [ $# -gt 0 ]; do

   if [[ $1 == *"--"* ]]; then
        v="${1/--/}"
        declare $v="$2"
   fi

  shift
done

এটির মতো পাস করুন my_script --p_out /some/path --arg_1 5এবং তারপরে স্ক্রিপ্টে আপনি $arg_1এবং ব্যবহার করতে পারেন $p_out


আমার এই সমাধানটি কেএসএইচ ৮৮-তে আমার পছন্দ হয়েছে v=``echo ${1} | awk '{print substr($1,3)}'`` typeset $v="$2"(প্রতিটি পাশের একটি করে ব্যাকটিক সরান)
hol

-2

যদি কোনও ফাংশন বা কোনও অ্যাপ্লিকেশনটিতে শূন্যের চেয়ে বেশি আর্গুমেন্ট থাকে তবে এর সর্বদা সর্বশেষ যুক্তি থাকে।

আপনি যদি বিকল্পের পতাকা এবং মান জোড়া পড়তে চান তবে এখানে: $ ./t.sh -o output -i input -l last

এবং আপনি বিকল্প / মান জোড়ার একটি পরিবর্তনশীল নম্বর গ্রহণ করতে চান,

এবং একটি বিশাল "যদি .. তবে .. অন্য .. ফাই" গাছ চান না,

তারপরে অ-শূন্য এবং এমনকি একটি আর্গুমেন্ট গণনা পরীক্ষা করার পরে,

দেহ হিসাবে এই চারটি বিভক্ত বিবৃতি দিয়ে কিছুক্ষণ লুপ লিখুন, তারপরে লুপের মধ্য দিয়ে প্রতিটি পাসে দুটি মান নির্ধারণ করে একটি কেস স্টেটমেন্ট থাকে।

স্ক্রিপ্টিংয়ের জটিল অংশটি এখানে প্রদর্শিত হয়:

#!/bin/sh    

# For each pair - this chunk is hard coded for the last pair.
eval TMP="'$'$#"
eval "PICK=$TMP"
eval TMP="'$'$(($#-1))"
eval "OPT=$TMP"

# process as required - usually a case statement on $OPT
echo "$OPT \n $PICK"

# Then decrement the indices (as in third eval statement) 

:<< EoF_test
$ ./t.sh -o output -i input -l last
-l 
last
$ ./t.sh -o output -l last
-l 
last
$ ./t.sh  -l last
-l 
last
EoF_test

-3
mitsos@redhat24$ my_script "a=1;b=mitsos;c=karamitsos"
#!/bin/sh
eval "$1"

আপনি স্ক্রিপ্ট স্কোপের ভিতরে সবেমাত্র কমান্ড লাইন প্যারামিটারগুলি ইনজেকশন করেছেন!


3
এটি ওপি নির্দিষ্ট সিনট্যাক্সের সাথে কাজ করে না; তারা চায়-a 1 -b mitsos -c karamitsos
মাইকেল মরোজেক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.