私は変数から複雑なコマンドを構築するシェルスクリプトに取り組んでいます。たとえば、次のようにします(Bash FAQから学んだテクニックを使用)。
#!/bin/bash
SOME_ARG="abc"
ANOTHER_ARG="def"
some_complex_command \
${SOME_ARG:+--do-something "$SOME_ARG"} \
${ANOTHER_ARG:+--with "$ANOTHER_ARG"}
このスクリプトはパラメーター--do-something "$SOME_ARG"を動的に追加--with "$ANOTHER_ARG"しsome_complex_command、これらの変数が定義されているかどうかを確認します。これまでのところ、これは正常に動作しています。
しかし、コマンドを実行しているとき(たとえば、スクリプトがデバッグモードで実行されているとき)に、コマンドを印刷またはログに記録できるようにしたいと思っています。そのため、スクリプトを実行するときに、some_complex_command --do-something abc --with defこのコマンドを変数に含めて、syslogに記録できるようにしたいと考えています。
Bash FAQは、この目的でトラップと変数(たとえば、デバッグ目的)を使用DEBUG$BASH_COMMANDする手法を示しています。私は次のコードでそれを試しました:
#!/bin/bash
ARG="test string"
trap 'COMMAND="$BASH_COMMAND"; trap - DEBUG' DEBUG
echo "$ARG"
echo "Command was: ${COMMAND}"
これは機能しますが、コマンドの変数は展開されません。
host ~ # ./test.sh
test string
Command was: echo "$ARG"
展開echo "$ARG"するにはevalを使用する必要があると思いますecho test string(少なくとも、evalまだ方法を見つけていません)。以下は機能します:
eval echo "Command was: ${COMMAND}"
次の出力が生成されます。
host ~ # ./test.sh
test string
Command was: echo "$ARG"
Command was: echo test string
しかしeval、このように安全に使用できるかどうかは本当にわかりません。私はいくつかのことを悪用することに失敗しました:
#!/bin/bash
ARG="test string; touch /x"
DANGER='$(touch /y; cat /etc/shadow)'
trap 'COMMAND="$BASH_COMMAND"; trap - DEBUG' DEBUG
echo "$ARG" $DANGER
echo "Command was: ${COMMAND}"
eval echo "Command was: ${COMMAND}"
これはうまく処理しているようですが、他の誰かが私が見逃した問題を見つけたのかどうか知りたいです。