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


848

আমি একটি খুব সাধারণ স্ক্রিপ্ট লিখছি যা অন্য স্ক্রিপ্টকে কল করে এবং আমার বর্তমান স্ক্রিপ্ট থেকে আমি যে স্ক্রিপ্টটি চালাচ্ছি তাতে আমার পরামিতিগুলি প্রচার করতে হবে।

উদাহরণস্বরূপ, আমার স্ক্রিপ্টের নাম foo.shএবং কলগুলিbar.sh

foo.sh:

bar $1 $2 $3 $4

আমি প্রতিটি প্যারামিটারকে স্পষ্টভাবে নির্দিষ্ট না করে কীভাবে এটি করতে পারি?



এছাড়াও দেখুন
স্ট্যাকওভারফ্লো.

উত্তর:


1402

আপনি যদি প্যারামিটারগুলি একইভাবে পাস করতে চান তবে "$@"প্লেইনের পরিবর্তে ব্যবহার করুন $@

পালন:

$ cat foo.sh
#!/bin/bash
baz.sh $@

$ cat bar.sh
#!/bin/bash
baz.sh "$@"

$ cat baz.sh
#!/bin/bash
echo Received: $1
echo Received: $2
echo Received: $3
echo Received: $4

$ ./foo.sh first second
Received: first
Received: second
Received:
Received:

$ ./foo.sh "one quoted arg"
Received: one
Received: quoted
Received: arg
Received:

$ ./bar.sh first second
Received: first
Received: second
Received:
Received:

$ ./bar.sh "one quoted arg"
Received: one quoted arg
Received:
Received:
Received:

7
এটি উদ্ধৃত / পলায়নযোগ্য স্ট্রিংগুলির মধ্য দিয়ে বিশুদ্ধ পাসের জন্য এই কাজটি করে: পর্যবেক্ষণ: বিড়াল #ync_foo.sh #! / বিন / বাশ প্রতিধ্বনি "$ @" "rsync" $ @ "./rsync_foo.sh -n" বার আমাকে "বার 2 বার বার 2 স্কিপিং ডিরেক্টরি বার করুন আমাকে কী শেল স্ক্রিপ্ট পাওয়া সম্ভব যা সত্যিকারের মূল কমান্ড লাইনটি উদ্ধৃতি বা পালানো স্ট্রিং সহ সম্পূর্ণ দেখতে পাবে?
মার্ক এডিংটন

3
পতাকা উত্তীর্ণ সম্পর্কে কি? যেমন, './bar.sh - সহ-স্টাফ'
নাথান লং

4
আমি যে কেউ ওয়ার্ড স্প্লিটিংয়ের বিষয়টিকে আরও
রানি আলবেগ ওয়েইন

4
আমি আপনাকে 'arg with spaces'তিনটি উদাহরণের জন্য একটি অন্তর্ভুক্ত করলে কী হয় তা দেখানোর পরামর্শ দিই । ফলাফল দেখে আমি অবাক হয়েছি; আশা করি আপনি তাদের ব্যাখ্যা করতে পারেন।
মাইকেল শ্যাপার

2
@ মিশেলশেপার, যাইহোক, ./foo.sh "arg with spaces"এবং ./foo.sh 'arg with spaces'100% অভিন্ন, সুতরাং প্রদত্ত উদাহরণগুলিতে এটি যুক্ত করার পরামর্শ কীভাবে সহায়ক হবে তা আমি দেখতে পাচ্ছি না।
চার্লস ডাফি

475

জন্য ব্যাশ এবং অন্যান্য বোর্ন মত শাঁস:

java com.myserver.Program "$@"

13
@Amir: না, না csh শেল । প্রত্যেকের সন্তুষ্টির জন্য: স্ক্রিপ্ট স্ক্রিপ্ট করবেন না । তবে আমি মনে করি সম্ভবত $argv:qকিছু csh রূপে কাজ করবে।
ক্রিস জনসন

2
ধন্যবাদ! পছন্দসই হিসাবে, এটি স্ক্রিপ্ট দ্বারা প্রাপ্ত একই আর্গুমেন্টগুলির পাস করে - একটি বড় তর্ক নয়। ডাবল-কোট প্রয়োজনীয়। এমনকি শূন্যস্থান অন্তর্ভুক্ত উদ্ধৃতি যুক্তি দিয়ে কাজ করে।
অ্যান্ডি টমাস

24
সম্পর্কিত: যদি আপনার শেল স্ক্রিপ্টটি জাভা চালানোর জন্য কেবল একটি মোড়ক হিসাবে কাজ করে তবে শেষ পংক্তিটি তৈরির বিষয়টি বিবেচনা করুন exec java com.myserver.Program "$@"এটি বাশার সম্পূর্ণ হওয়ার জন্য অপেক্ষা না করে জাভাতে সম্পাদন করে causes সুতরাং, আপনি আরও একটি প্রক্রিয়া স্লট ব্যবহার করছেন। এছাড়াও, যদি পিতামাতার প্রক্রিয়াটি (যা আপনার স্ক্রিপ্টটি চালায়) পিডের মাধ্যমে এটি পর্যবেক্ষণ করে এবং এটি 'জাভা' প্রক্রিয়া হওয়ার প্রত্যাশা করে, আপনি যদি কোনও এক্সিকিউট না করেন তবে কিছু অসাধারণ জিনিস ভঙ্গ হতে পারে; এক্সিকিউট এর ফলে জাভা একই পিডের উত্তরাধিকারী হয়।
গ্রেগো

7
@dragonxlwang: আপনি একটি অ্যারের পরিবর্তনশীল ব্যবহার করতে পারে, যদি আপনার শেল তাদের সমর্থন (যেমন ব্যাশ , zsh অন্যান্যের কিন্তু প্লেইন না Bourne- বা POSIX-শেল): সংরক্ষণ args সঙ্গে args=("$@")এবং একটি পৃথক শেল "শব্দ" হিসেবে প্রতিটি উপাদান প্রসারিত ( অনুরূপ "$@") সাথে "${args[@]}"
ক্রিস জনসেন

1
ব্যবহার করার সময় মনে রাখার জন্য কি কোনও "গ্যাটাচস" রয়েছে "$@", যদি আপনি কোনও যুক্তি বা শূন্য চরিত্রগুলি বা অন্য বিশেষ চরিত্রগুলিতে ফাঁকা স্থান থেকে পালিয়ে যান তবে তা কী ব্যর্থ হবে?
আইকিউআন্দ্রিয়াস

97

ব্যবহার "$@"(সমস্ত POSIX তুলনামূলক জন্য কাজ করে )।

[...], বাশটিতে "$ @" ভেরিয়েবল বৈশিষ্ট্য রয়েছে যা স্পেস দ্বারা বিভাজিত সমস্ত কমান্ড-লাইন প্যারামিটারগুলিতে প্রসারিত হয়।

উদাহরণস্বরূপ বাশ থেকে ।


6
সুতরাং "$ @" কি কেবল $ @ এর আশেপাশে উদ্ধৃতিগুলি নয় তবে কার্যকরভাবে পরিবর্তনশীলতে ভিন্ন নির্মিত?
বেন

5
@ বেন এটি একটি একক পরিবর্তনশীল তবে এর চারপাশে ডাবল উদ্ধৃতি প্রয়োজন (ভাঙা) থেকে পৃথকভাবে একটি কার্যকর মূল্য পৃথক করতে $*। আমি বিশ্বাস করি এখানে historicalতিহাসিক অগ্রগতি আছে; $*নকশা অনুযায়ী কাজ করেনি, তাই $@এটি প্রতিস্থাপনের জন্য উদ্ভাবিত হয়েছিল; তবে কোটিং বিধিগুলি সেগুলি হওয়ায় তার চারপাশের দ্বিগুণ উদ্ধৃতিগুলি এখনও প্রয়োজনীয় (বা এটি ভাঙা $*শব্দার্থে ফিরে যাবে )।
ট্রিপলি

7
"তাহলে কি" $ @ "কেবল প্রায় $ @ এর উদ্ধৃতি নয়, তবে বাস্তবে পরিবর্তনশীলতে ভিন্ন নির্মিত?" - সমস্ত অভিপ্রায় এবং উদ্দেশ্যে, হ্যাঁ: স্ট্যাকওভারফ্লো.com
স্টুয়ার্ট বার্গ

1
যদি আপনি কোনও স্ক্রিপ্টকে কল echo "$@"করেন ./script.sh a "b c" dতবে a b c dতার পরিবর্তে আপনি পাবেন a "b c" d, যা খুব আলাদা।
ইসরান্দি

7
@ আইসারাণ্ডি যদিও এটি সত্য যে আউটপুটটিতে আর কোট থাকে না, তবে আপনি যা প্রত্যাশা করবেন ... তবে বিশ্রামের সাথে নিশ্চিত হয়ে নিন যে স্ক্রিপ্টের মধ্যে echoতিনটি যুক্তি রয়েছে: "a" "b c" "d"(তারপরে শেলটি তার স্ট্রিং প্রসারণের অংশ হিসাবে তাদের সাথে যোগ দেয়)। তবে আপনি যদি ব্যবহার করতেন তবে আপনি for i in "$@"; do echo $i; doneপেয়েছেন a⏎b c⏎d
এফআরডি

64

আমি বুঝতে পারি এটির উত্তরের জবাব দেওয়া হয়েছে তবে এখানে "$ @" $ @ "$ *" এবং $ * এর মধ্যে একটি তুলনা করা হয়েছে

পরীক্ষার স্ক্রিপ্টের উপাদানসমূহ:

# cat ./test.sh
#!/usr/bin/env bash
echo "================================="

echo "Quoted DOLLAR-AT"
for ARG in "$@"; do
    echo $ARG
done

echo "================================="

echo "NOT Quoted DOLLAR-AT"
for ARG in $@; do
    echo $ARG
done

echo "================================="

echo "Quoted DOLLAR-STAR"
for ARG in "$*"; do
    echo $ARG
done

echo "================================="

echo "NOT Quoted DOLLAR-STAR"
for ARG in $*; do
    echo $ARG
done

echo "================================="

এখন, বিভিন্ন যুক্তি দিয়ে পরীক্ষা স্ক্রিপ্টটি চালান:

# ./test.sh  "arg with space one" "arg2" arg3
=================================
Quoted DOLLAR-AT
arg with space one
arg2
arg3
=================================
NOT Quoted DOLLAR-AT
arg
with
space
one
arg2
arg3
=================================
Quoted DOLLAR-STAR
arg with space one arg2 arg3
=================================
NOT Quoted DOLLAR-STAR
arg
with
space
one
arg2
arg3
=================================

1
ভাল উত্তরসূচী প্রদর্শন এবং এই উত্তরের অবদান।
মের্লিন

33
#!/usr/bin/env bash
while [ "$1" != "" ]; do
  echo "Received: ${1}" && shift;
done;

কীভাবে আপনার স্ক্রিপ্টে অর্গগুলি আসে তা পরীক্ষা করার চেষ্টা করার সময় এটি কিছুটা বেশি কার্যকর হতে পারে বলে ভেবেছিলেন


6
এটি অবশ্যই তাঁর প্রশ্নের উত্তর দিতে সহায়তা করে নি তবে এটি সত্যই কার্যকর। upvoted!
দারিও রুশো

2
খালি প্যারামিটারটি পাস করার পরে এটি ভেঙে যায়। আপনার যাচাই করা উচিত$#
সেবি

ভাল args পরীক্ষক, একমত "", ''একটি আর্গুমেন্ট হিসাবে, এছাড়াও যদি কোন args ছিল এটা নীরব। আমি এটি ঠিক করার চেষ্টা করেছি, তবে লুপ এবং কাউন্টারের জন্য দরকার $#। আমি কেবল শেষের দিকে এটি যুক্ত করেছি:echo "End of args or received quoted null"
মের্লিন

8

আমার সান ইউনিক্সের অনেকগুলি সীমাবদ্ধতা রয়েছে, এমনকি "$ @" কে পছন্দসই হিসাবে ব্যাখ্যা করা হয়নি। আমার কর্মসংস্থান $ {@}} উদাহরণ স্বরূপ,

#!/bin/ksh
find ./ -type f | xargs grep "${@}"

যাইহোক, আমার এই বিশেষ স্ক্রিপ্টটি থাকতে হয়েছিল কারণ আমার ইউনিক্সটি গ্রেপ -আর সমর্থন করে না


এটি একটি বাশ প্রশ্ন; আপনি ব্যবহার করছেনksh
ট্রিপলি

6

যদি আপনি $@অন্যান্য অক্ষরগুলির সাথে একটি উদ্ধৃত স্ট্রিংয়ের মধ্যে অন্তর্ভুক্ত করেন তবে একাধিক যুক্তি উপস্থিত থাকলে আচরণটি খুব অদ্ভুত হয় তবে কেবল প্রথম যুক্তিকে উদ্ধৃতিগুলির মধ্যে অন্তর্ভুক্ত করা হয়।

উদাহরণ:

#!/bin/bash
set -x
bash -c "true foo $@"

উৎপাদনের:

$ bash test.sh bar baz
+ bash -c 'true foo bar' baz

তবে প্রথমে ভিন্ন ভিন্ন ভেরিয়েবলকে নিয়োগ দেওয়া:

#!/bin/bash
set -x
args="$@"
bash -c "true foo $args"

উৎপাদনের:

$ bash test.sh bar baz
+ args='bar baz'
+ bash -c 'true foo bar baz'

3
আমি তা অস্বীকার করব না, তবে এটি আসলে "$@"ব্যাশ-এর শব্দার্থক শব্দগুলির মধ্যে অর্থবোধ করে। এছাড়া মধ্যে কী পার্থক্য চিত্রিত সাহায্য করে $@এবং $*এবং কেন তারা উভয় দরকারী করছি। থেকে bash(1)man পৃষ্ঠা বিশেষ পরামিতি অধ্যায়: " *- সম্প্রসারণ উদ্ধৃতি চিহ্ন মধ্যে ঘটে, তখন তা একটি একক শব্দ প্রতিটি পরামিতি [...] অর্থাৎ মান বিস্তৃতি "$*"সমতূল্য থেকে "$1c$2c...", যেখানে cহয় [ $IFS]।" এবং প্রকৃতপক্ষে, আপনার প্রথম উদাহরণের $*পরিবর্তে ব্যবহার $@করে দ্বিতীয় সংস্করণের মতো আউটপুট জাল করে।
এফআরডি

2
এখন, এর সাথে তুলনা করুন "$@"। ম্যান পৃষ্ঠা থেকে আবার: " @- যখন ডাবল উদ্ধৃতিগুলির মধ্যে প্রসারণ ঘটে তখন প্রতিটি প্যারামিটার পৃথক শব্দের দিকে প্রসারিত হয় That অর্থাৎ "$@"সমান হয় "$1" "$2"... যদি কোনও শব্দের মধ্যে ডাবল-কোটড প্রসারণ ঘটে তবে প্রথম প্যারামিটারের বিস্তৃতি যোগ হয় মূল শব্দের শুরুর অংশ এবং শেষ প্যারামিটারের বিস্তৃতি মূল শব্দের শেষ অংশের সাথে যুক্ত হয়েছে। ... এবং প্রকৃতপক্ষে, যদি আপনার কোডটি হয়ে থাকে bash -c "true foo $@ bar baz", তবে এটি test.sh one twoনেট হিসাবে চালানো bash -c 'true foo one' 'two bar baz'
এফআরডি

1
দস্তাবেজগুলির উদ্ধৃতি এবং এ সম্পর্কিত তথ্যের জন্য ধন্যবাদ $*, আমি মনে করি এটি বিদ্যমান আছে ভুলে
যাচ্ছি

হেহ। আমি বিপরীত, $@আমি প্রথম শেল স্ক্রিপ্টিং শুরু করার সময় কেবল ক্রেশন অর্জন করছিলাম, এখনও আমি নিজেকে সেখানে স্মরণ করিয়ে দিতে হবে। "$*"স্ক্রিপ্টগুলিতে ব্যবহৃত দেখা সাধারণ ছিল ... তারপরে লেখক বুঝতে পারতেন যে এটি তাদের সমস্ত যুক্তি একসাথে ছড়িয়ে দিচ্ছে, তাই তারা শব্দ বিভক্তকরণের মাধ্যমে সমস্ত ধরণের জটিল বাজে চেষ্টা করে "$*"বা [আবার] লুপিং দ্বারা একটি আর্গ তালিকার একত্রিত করবে উপর shiftতাদের একের পর এক চূর্ণ করতে ... শুধু ব্যবহার $@সমাধান করুন। (সহায়তা করে যে ব্যাশ অ্যারে সদস্যদের অ্যাক্সেস করতে একই মেমোনিক ব্যবহার করে, এছাড়াও: ${var[*]}তাদের সকলের ${var[@]}জন্য শব্দ হিসাবে, শব্দের তালিকার জন্য))
ফেব্রুয়ারী

এখানে আসল সমস্যাটি হ'ল আপনি এমন bash -cকোনও উপায়ে ব্যবহার করছেন যা একেবারেই কোনও বোধগম্য নয়।
ট্রিপলি

4

কখনও কখনও আপনি আপনার সমস্ত যুক্তিগুলি পাস করতে চান তবে একটি পতাকা (যেমন --flag) এর আগে

$ bar --flag "$1" --flag "$2" --flag "$3"

আপনি নিম্নলিখিত পদ্ধতিতে এটি করতে পারেন:

$ bar $(printf -- ' --flag "%s"' "$@")

দ্রষ্টব্য: অতিরিক্ত ক্ষেত্রের বিভাজন এড়াতে আপনার অবশ্যই উদ্ধৃতি দিতে হবে %sএবং $@, এবং একটি স্ট্রিং থাকা এড়ানোর জন্য, আপনি সাবসেলের উদ্ধৃতি দিতে পারবেন না printf


3

আপনার শূন্যস্থান বা পালানো অক্ষরগুলি বাদ দিলে সূক্ষ্মভাবে কাজ করে। আমি এই ক্ষেত্রে আর্গুমেন্ট ক্যাপচার এবং স্ক্রিপ্টের ভিতরে এসএসএসে প্রেরণের উপায় খুঁজে পাই না।

এটি দরকারী হতে পারে তবে এটি কুরুচিপূর্ণ

_command_opts=$( echo "$@" | awk -F\- 'BEGIN { OFS=" -" } { for (i=2;i<=NF;i++) { gsub(/^[a-z] /,"&@",$i) ; gsub(/ $/,"",$i );gsub (/$/,"@",$i) }; print $0 }' | tr '@' \' )

3

এখানে প্রচুর উত্তরের সাথে $@বা $*উক্তি ব্যতীত প্রস্তাব দেওয়া হয় বা দেওয়া হয়, তবে এগুলি আসলে কী করে এবং আপনাকে কেন সেভাবে করা উচিত তা কিছুই ব্যাখ্যা করতে পারে বলে মনে হয় না। সুতরাং আমাকে এই উত্তর থেকে এই দুর্দান্ত সারাংশ চুরি করা যাক :

এখানে চিত্র বর্ণনা লিখুন

লক্ষ্য করুন যে উদ্ধৃতিগুলি সমস্ত পার্থক্য করে এবং এগুলি উভয় ছাড়াই অভিন্ন আচরণ রয়েছে।

আমার উদ্দেশ্যটির জন্য, আমাকে একটি স্ক্রিপ্ট থেকে অন্য স্ক্রিপ্টে যেমনটি রয়েছে তেমন প্যারামিটারগুলি পাস করতে হবে এবং তার জন্য সেরা বিকল্পটি হ'ল:

# file: parent.sh
# we have some params passed to parent.sh 
# which we will like to pass on to child.sh as-is

./child.sh $*

কোন উদ্ধৃতি লক্ষ্য করুন $@এবং উপরের পরিস্থিতিতে পাশাপাশি কাজ করা উচিত।


2

bar "$@" সমান হবে bar "$1" "$2" "$3" "$4"

লক্ষ্য করুন যে উদ্ধৃতি চিহ্নগুলি গুরুত্বপূর্ণ!

"$@", $@, "$*"বা $*হবে প্রতিটি আচরণ সামান্য পলায়নের এবং সংযুক্তকরণের এই বর্ণনা অনুযায়ী সংক্রান্ত বিভিন্ন Stackoverflow উত্তর

একটি ঘনিষ্ঠভাবে সম্পর্কিত ব্যবহারের কেসটি প্রদত্ত সমস্ত আর্গুমেন্টকে এই জাতীয় যুক্তির মধ্যে দিয়ে যাচ্ছে :

bash -c "bar \"$1\" \"$2\" \"$3\" \"$4\""

আমি এটি অর্জনের জন্য @ কাওয়ান্টরের উত্তরের বিভিন্নতা ব্যবহার করছি:

bash -c "bar $(printf -- '"%s" ' "$@")"

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