複数のパラメータを単一の文字列として外部プログラムに渡す

複数のパラメータを単一の文字列として外部プログラムに渡す

次のようにbashスクリプトに複数のパラメータを渡したいと思います。単一文字列パラメータ外部実行ファイル(特にgit

次の内容を表すいくつかの答えを見つけました。

"'$*'"
"'$@'"

渡されるとかなり良く見えますが、echo外部プログラムに渡すと失敗します。パイプも同様ですecho

これはMWEです:

#!/bin/bash

# preparation
git init .
git add -A

echo git commit -m "'$@'" # works when copied to terminal
git commit -m "'$@'" # fails if more than one parameter given
git commit -m $(echo "'$@'") # fails if more than one parameter given

rm -rf .git # c

結果:

$ bash test.sh test2 test2
empty Git-Repository in /tests/bash-scripts/.git/ initialized
git commit -m 'test1 test2'
error: pathspec 'test2'' did not match any file(s) known to git.
error: pathspec 'test2'' did not match any file(s) known to git.

複数のスクリプトパラメータを次のように渡す方法単一文字列""(スペースを含む)を外部実行可能ファイルに変換します(スクリプト呼び出しでラップしない)。


私はこれがうまくいくことを知っていました。

 git commit -m "$(echo "'$@'")"

しかし、これは私を次のステップに導きます。

-mパラメータが指定されていない場合は、コミットメッセージエディタが起動されるようにパラメータを省略したいと思います。

if [ 0 != $# ]
then
  MESSAGE ="-m " "$(echo "'$@'")"
fi
git commit $MESSAGE

または

if [ 0 != $# ]
then
  MESSAGE =("-m " "$(echo "'$@'")")
fi
echo 
git commit ${MESSAGE[@]}

woseが再び失敗しても、引用された単語は分離されます。

$bash test.sh "test1 test2" test3
git commit -m 'test1 test2 test3'
error: pathspec 'test2' did not match any file(s) known to git.
error: pathspec 'test3'' did not match any file(s) known to git.

答え1

すべての引数を文字列として解釈するには、次のようにします。

"$*"

つまり

git commit -m "$*"

man bash「特殊パラメータ」の下に文書化されています。

*1から始まる位置パラメータに展開されます。拡張が二重引用符内にない場合、各位置引数は別々の単語に展開されます。これらの単語は、実行されるコンテキストで単語分割とパス名拡張がさらに適用されます。二重引用符内で拡張が発生すると、単一の単語に展開され、各引数の値はIFS特殊変数の最初の文字で区切られます。つまり、IFS変数値の最初の文字がどこにあるか"$*"と同じです。設定しないと、パラメータはスペースで区切られます。 nullの場合、パラメータは区切り文字を挿入せずに連結されます。"$1c$2c..."cIFSIFS

関連情報