28

notify-finish任意のコマンドの前に追加できるスクリプトを作成しようとしています。完了すると、次の引数で指定されたコマンドが実行され、コマンドが完了したときにユーザーに電子メールが送信されます。これが私が持っているものです:

PROG=$1
# Run command given by arguments
$@
ECODE=$?
echo -e "Subject: `hostname`: $PROG finished\r\nTo: <$USER>\r\n\r\nExited with $ECODE\r\n" | sendmail $USER

これはほとんどの場合機能しますが、引数にスペースが含まれている場合、引用符は削除されます。

実例:

notify-finished rsync -avz source/ user@remote:dest/

失敗例:

notify-finished rsync -avz -e 'ssh -c blowfish' source/ user@remote:dest/

2番目のケースで$@は、はに展開されrsync -avz -e ssh -c blowfish source user@remote:dest/、一重引用符が欠落しています。二重引用符でも、。でも機能しません$*

他の投稿を読んだ後、コマンドを配列に入れてみましたが、まったく同じ問題が発生します。

CMD=(notify-finished rsync -avz -e 'ssh -c blowfish' source/ user@remote:dest/)
${CMD[@]}

これをすべての引数で機能させるにはどうすればよいですか?

4

2 に答える 2

28

"$@" 引用符で使用:

prog="$1"
"$@"
ecode="$?"
echo "$prog exited with $ecode"

これにより、受信したとおりに各引数が渡されます。引用符を含めない場合、各要素は次のように分割され$IFSます。

  • "$@"のようなもの"$1" "$2" "$3" ...で、各要素を個別の引数として渡します。
  • "$*"のようなもの"$1 $2 $3 ..."で、連結されたすべての要素を単一の引数として渡します
  • $*$@ようなもの$1 $2 $3 ...で、空白の各要素を分割し、すべてのグロブを展開し、結果の各単語を個別の要素($IFS)として渡します。

"${array[@]}"やなどの配列についても同じことが言えます。"${array[*]}"

于 2011-04-19T17:22:59.800 に答える
4

変数の置換を二重引用符で囲んで、それらが解析されないようにします(これはすべての変数に適用されることに注意してください:、、、$@および$1$PROG。また、変数名に割り当てるときは、変数名の前に$を付けないでください。#コメントに使用します。そして、最後の行では、一重引用符は変数がまったく置換されないようにします。

PROG="$1"
shift
# Run program below
"$PROG" "$@"
ECODE=$? # note: this will always be a number, so it doesn't have to be protected with double-quotes
echo -e "Subject: $(hostname): $PROG finished\r\nTo: <$USER>\r\n\r\nExited with $ECODE\r\n' | sendmail "$USER"
于 2011-04-19T17:42:03.860 に答える