
Ubuntu16.04
元のコマンドをログファイルに反映したいと思います。私のログファイルは次のようになります。
Mon 04/16/18 04-24-pm - Executing command: sudo /home/editini.sh "one" "two" "three" "four" "five" "six"
スペルチェックを満たしながらこれを達成する最も簡単な方法は何ですか?
#!/bin/bash
hello="${1}"
my="$2"
friend="$3"
are="$4"
you="$5"
safe="$6"
timeStamp="$(date '+%a %D %m-%S-%P')"
rm -rf report*; touch report.txt;
{
echo "$timeStamp - Executing command: sudo /home/editini.sh \"$hello\" \"$my\" \"$friend\" \"$are\" \"$you\" \"$safe\""
echo ""
echo "$timeStamp" - Executing command: sudo /home/editini.sh "$*"
echo "";
echo "$timeStamp" - Executing command: sudo /home/editini.sh \""$*"\"
echo "";
} > report.txt
cat report.txt
パラメータを事前に知っておく必要があるため、最初の行を選択することはできません。
上記のコマンドを実行すると、コンソールにこのような内容が表示されます。
root@me /home/scripts/vent-commands # sh one.sh one two three four five six
Mon 04/16/18 04-05-pm - Executing command: sudo /home/editini.sh "one" "two" "three" "four" "five" "six"
Mon 04/16/18 04-05-pm - Executing command: sudo /home/editini.sh one two three four five six
Mon 04/16/18 04-05-pm - Executing command: sudo /home/editini.sh "one two three four five six"
答え1
あなたは得ることができますシェルから引用以下を使用して出力@Q
拡張修飾子Bash 4.4以降:
$ echo "$timeStamp" - Executing command: sudo /home/editini.sh "${@@Q}"
Mon 04/16/18 04-05-pm - Executing command: sudo /home/editini.sh 'one' 'two' 'three' 'four' 'five' 'six'
二重引用符ではなく一重引用符を使用しますが、シェルに入力として返されたときに出力が有効であることを確認し、期待どおりに実行されます。以下は重要な例ですが、ログ形式に二重引用符が必要な場合は役に立ちません。
やや混乱するように、連続文字に${@@Q}
使用する@
ことは2つの異なる意味を持ちます。最初は@
パラメータ配列を表し、2番目は配列拡張の出力を変換する修飾子を導入します。修飾子はQ
出力を引用します。$@
対照的に、各要素は個別に拡張されます$*
が、おそらくこの場合は重要ではありません(実際のコードがより複雑な場合は重要かもしれません)。
@Q
、、、、、printf %q
一重引用符は、他のシェル拡張を抑制するために使用します。引数の1つに、、、、$
またはが含まれている場合は、二重`
引用符を持つすべての項目が疑われます。確実にする\
"
!
@Q
すべてこの用語は必ずしも必要ではありませんが(そしてそうでprintf
ないにもかかわらず)引用されています。空白は依然として正しく処理されます。
$ set -- 'o$ne' "t w o" th\`ree fo\\ur five\! s\"i\'x
$ echo "$timeStamp" - Executing command: sudo /home/editini.sh "${@@Q}"
Mon 04/16/18 04-05-pm - Executing command: sudo /home/editini.sh 'o$ne' 't w o' 'th`ree' 'fo\ur' 'five!' 's"i'\''x'
コマンドを再度コピーすると、入力がどんなに奇妙であっても動作します。
答え2
これはうまくいくようです:
#!/bin/bash
a=$(parallel --shellquote ::: "$@")
echo "$timeStamp" - Executing command: sudo /home/editini.sh $a
試験用:
mylog '"I want a 2"x4"", said the 3 * captain"' to his friend
(テストでわかるように)"は入力の一部である可能性があるため、""として引用しません。代わりに\を使用してください。驚きます。
答え3
シンプルループの使用
{
echo -n "$timeStamp - Executing command: sudo /home/editini.sh"
for a in "$@"
do
echo -n " \"$a\""
done
echo
} > report.txt
例えば
./x one two "three and four together" five
Mon 04/16/18 04-46-pm - Executing command: sudo /home/editini.sh "one" "two" "three and four together" "five"
これを破ることができる1つは、入力に"
次のものがある場合です。
% ./x one "two\"three" four
Mon 04/16/18 04-21-pm - Executing command: sudo /home/editini.sh "one" "two"three" "four"