web-dev-qa-db-ja.com

Bashシェルスクリプト内のすべての引数を伝播する

私は別のスクリプトを呼び出す非常に単純なスクリプトを書いています、そして私は現在のスクリプトから実行しているスクリプトにパラメータを伝播する必要があります。

たとえば、私のスクリプト名はfoo.shで、bar.shを呼び出します。

foo.sh:

bar $1 $2 $3 $4

各パラメータを明示的に指定せずにこれを行うにはどうすればよいですか?

677
Fragsworth

実際にパラメータに同じものを渡したい場合は、普通の"$@"ではなく$@を使用してください。

観察する:

$ 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:
1137

bash およびその他のBourneライクシェルの場合

Java com.myserver.Program "$@"
458
Chris Johnsen

"$@"を使用してください(すべての _ posix _ 互換性に対して機能します)。

[...]、bashは "$ @"変数を特徴としています。これはスペースで区切られたすべてのコマンドラインパラメータに展開されます。

からbash - を例として。

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

引数があなたのスクリプトにどのように入ってくるかをテストしようとするときにこれがもう少し役に立つかもしれないとちょうど思った

29
Gregory Patmore

私はこれがよく答えられていることを理解していますが、これは "$ @" $ @ "$ *"と$ *の比較です。

テストスクリプトの内容

# 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
=================================
27
JDS

私のSunのUnixには多くの制限があり、たとえ "$ @"でも望み通りには解釈されませんでした。私の回避策は$ {@}です。例えば、

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

ちなみに、私のUNIXもgrep -rをサポートしていないので、私はこの特定のスクリプトを持っていなければなりませんでした

7
Hampden123

スペースやエスケープ文字がある場合を除き、問題なく動作します。この場合、引数を取り込んでスクリプト内のSSHに送信する方法が見つかりません。

これは役に立つかもしれませんがとても醜いです

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

他の文字とともに引用符付き文字列に$@を含めると、複数の引数があるときの動作は非常に奇妙になり、最初の引数だけが引用符の内側に含まれます。

例:

#!/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'
2
ColinM