コマンドを実行してファイルに追加する一般的なスクリプトが必要です。
私の試みは次のとおりです(という実行可能ファイルに保存されています./action
)。
#!/bin/bash
#runs command and logs result to "./actions"
if "$@"; then
echo "#"$(date)"(success)" >> ./actions
else
read -p "Exit code is fail. Still record to ./actions (y)? " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
exit 1
fi
echo "#"$(date)"(failed)" >> ./actions
fi
echo "$@" >> ./actions
私が経験している問題は次のとおりです。
./action touch "new file"
正しく実行されますが、bashは保存のみです。
touch new file
とは明らかにtouch new file
異なりますtouch "new file"
。
引用符付き引数を含むコマンドを正しく記録するようにこのスクリプトを変更するにはどうすればよいですか?
答え1
興味深い質問です。私はあなたが望むことが完全に可能であるとは思わないが、%q
Bashの実装で使用できる型指定子を使うとかなり近づくことができます。printf
%q は、printf がその引数をシェル入力として再利用できる形式で出力するようにします。
スクリプトの最後の数行は次のとおりです。
printf "%q\n" "$@" | tr '\n' ' ' >> actions
printf "\n" >> actions
これはコマンドを入力したまま記録するのではなく、シェルで使用するのに適した形式でコマンドを記録するため、記録されたコマンドを入力すると、もともと期待した結果が得られます。たとえば、次のようにします。
./action touch "new file"
あなたは以下を得ます:
#Wed Sep 4 14:10:57 CEST 2019(success)
touch new\ file
または以下を実行した後:
./action echo 'one
two
three
'
あなたは以下を得ます:
#Wed Sep 4 14:11:44 CEST 2019(success)
echo $'one\ntwo\nthree\n'
ちなみに、shellcheck
スクリプトに2つのバグが報告されました。
$ ~/.cabal/bin/shellcheck action
In action line 5:
echo "#"$(date)"(success)" >> ./actions
^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.
^-- SC2046: Quote this to prevent word splitting.
In action line 13:
echo "#"$(date)"(failed)" >> ./actions
^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.
^-- SC2046: Quote this to prevent word splitting.