web-dev-qa-db-ja.com

引用されたパラメーターを受信して​​再送信するためのBashスクリプト

ネストされたスクリプトで安全に受信できるように、bashスクリプトの引用されたパラメーターを取得しようとしています。何か案は?

test.sh

#!/bin/bash
echo $*
bash myecho.sh $*

myecho.sh

#!/bin/bash
 echo $1
 echo $2
 echo $3
 echo $4

サンプル:

bash test.sh aaa bbb '"ccc ddd"'

結果:

aaa bbb "ccc ddd"
aaa
bbb
"ccc
ddd"

望んだ結果

aaa bbb "ccc ddd"
aaa
bbb
ccc ddd
94
chilltemp
#!/bin/bash
echo $*
bash myecho.sh "$@"

「$ @」コンストラクトはbash固有ではなく、POSIXシェルで機能するはずです(少なくともダッシュでは機能します)。また、必要な出力が与えられている場合、余分なレベルの引用符はまったく必要ないことに注意してください。 I.E.上記のスクリプトを次のように呼び出すだけです。

./test.sh 1 2 "3 4"
67
pixelbeat

「$ @」(引用符で囲まれたドル)を使用して、パラメータを添え字に渡します。そのようです ....

ls-color.sh:

#!/bin/bash
/bin/ls --color=auto "$@"    # passes though all CLI-args to 'ls'


理由について.....

Bash manページ から:

$*-位置パラメータを1から開始して展開します。二重引用符内で展開すると、各パラメーターの値がIFS特殊変数の最初の文字で区切られた単一のWordに展開されます。つまり、"$*""$1c$2c..."と同等です。cはIFS変数の値の最初の文字です。 IFSが設定されていない場合、パラメーターはスペースで区切られます。 IFSがヌルの場合、パラメーターはセパレーターを介さずに結合されます。

$@-位置パラメータを1から開始して展開します。二重引用符内で展開すると、各パラメーターが個別のWordに展開されます。つまり、"$@""$1" "$2" ...と同じです。二重引用符で囲まれた展開がWord内で発生する場合、最初のパラメーターの展開は元のWordの先頭部分と結合され、最後のパラメーターの展開はパラメータは、元のWordの最後の部分と結合されます。位置パラメータがない場合、"$@"および$@は何も展開されません(つまり、削除されます)。


デモスクリプトの設定...

echo 'echo -e "\$1=$1\n\$2=$2\n\$3=$3\n\$4=$4"' > echo-params.sh
echo './echo-params.sh $*' > dollar-star.sh
echo './echo-params.sh $@' > dollar-at.sh
echo './echo-params.sh "$*"' > quoted-dollar-star.sh
echo './echo-params.sh "$@"' > quoted-dollar-at.sh
chmod +x *.sh

"$@"-quoted-dollar-atは、引数を再渡すための恒等変換サブシェルへ(〜99%の時間、これはあなたがすることを意図したものです):

./quoted-dollar-at.sh aaa '' "'cc cc'" '"ddd ddd"'
  # $1= aaa
  # $2=            
  # $3= 'cc cc'
  # $4= "ddd ddd"

"$*"-quoted-dollar-starは引数を単一の文字列に破壊します(〜あなたが実際にこの振る舞いを望んでいる時間の1%、例えば条件付き:if [[ -z "$*" ]]; then ...):

./quoted-dollar-star.sh aaa '' "'cc cc'" '"ddd ddd"'
  # $1= aaa  'cc cc' "ddd ddd"   
  # $2=                     
  # $3=             
  # $4=

$*/$@-引用符なしでは、どちらの形式も引用符の1レベルを取り除き、基になる文字列からスペースを解釈しますが、引用文字を無視します(ほとんどの場合これは間違いです)。

./dollar-star.sh aaa '' "'cc cc'" '"ddd ddd"'
  # $1= aaa
  # $2= 'cc                  
  # $3= cc'
  # $4= "ddd

./dollar-at.sh aaa '' "'cc cc'" '"ddd ddd"'
  # $1= aaa
  # $2= 'cc
  # $3= cc'
  # $4= "ddd

楽しみたい場合は、「$ @」を使用して好きなだけ深くネストし、必要に応じてargsスタックから要素をプッシュおよびポップできます。

function identity() {
  "$@"
}
set -x
identity identity identity identity identity echo Hello \"World\"
# + identity identity identity identity identity echo Hello '"World"'
# + identity identity identity identity echo Hello '"World"'
# + identity identity identity echo Hello '"World"'
# + identity identity echo Hello '"World"'
# + identity echo Hello '"World"'
# + echo Hello '"World"'
# Hello "World"
138
Dave Dopson