cron.dにコマンドを追加/エコーしようとしています。ただし、コマンドをエコーするスクリプトを実行するとき:
echo */2 * * * * /usr/bin/aws ssm-send-command --document-name "AWS-RunShellScript" --parameters '{"commands":["echo {{ssm:/mr2/cloudwatch-custom}}"]"}' --instance-ids "$INSTANCE_ID" --region us-east-1 >> /etc/cron.d/lvm_disk_space
次の内容を含むファイルを見つけました。
*/2 boot-finished cloud-config.txt datasource handlers obj.pkl scripts sem user-data.txt user-data.txt.i vendor-data.txt vendor-data.txt.i boot-finished cloud-config.txt datasource handlers obj.pkl scripts sem user-data.txt user-data.txt.i vendor-data.txt vendor-data.txt.i boot-finished cloud-config.txt datasource handlers obj.pkl scripts sem user-data.txt user-data.txt.i vendor-data.txt vendor-data.txt.i boot-finished cloud-config.txt datasource handlers obj.pkl scripts sem user-data.txt user-data.txt.i vendor-data.txt vendor-data.txt.i /usr/bin/aws ssm-send-command --document-name AWS-RunShellScript --parameters {"commands":["echo {{ssm:/mr2/cloudwatch-custom}}"]"} --instance-ids --region us-east-1
*
仕事がねじれたようです。引用符で囲みようとすると、常に次のような結果が得られます。
echo "*/2 * * * * /usr/bin/aws ssm-send-command --document-name "AWS-RunShellScript" --parameters '{"commands":["echo {{ssm:/mr2/cloudwatch-custom}}"]"}' --instance-ids "$INSTANCE_ID" --region us-east-1" >> /etc/cron.d/lvm_disk_space
./user-data.txt: line 30: unexpected EOF while looking for matching `"'
./user-data.txt: line 31: syntax error: unexpected end of file
引用符を避ける安全な方法はありますか?
答え1
最初のコマンドの問題は、*
文字が引用されないことです。したがって、シェルはそれを現在のディレクトリの一致するファイル名に拡張します。
2番目のコマンドの問題は、一重引用符と二重引用符の両方が含まれているため、crontabエントリを二重引用符として確実に引用できないことです。まず、単一の引用符(二重引用符など)のみを含め、別の引用符(一重引用符など)を使用してコマンド全体を引用するように再構築する必要があります。 crontabエントリにもスペルエラーがあります(何かわからないので修正しようとしません)。しなければならないbe)奇数の二重引用符があるからです。
より良いアプローチは、ここで引用した文書を使用することです。
cat >>/etc/cron.d/lvm_disk_space <<'END_CRON'
*/2 * * * * /usr/bin/aws ssm-send-command --document-name "AWS-RunShellScript" --parameters '{"commands":["echo {{ssm:/mr2/cloudwatch-custom}}"]"}' --instance-ids "$INSTANCE_ID" --region us-east-1
END_CRON
ここで参照されているリダイレクトを使用して、ファイルの末尾にリテラルテキストを書き込みます。最初のタグの周りの引用符のため、シェルはここで文書の内容を「刺す」(拡張または変更)しませんEND_CRON
。
コマンドに開く二重引用符がまだ含まれているため、直接変更する必要があります。
["echo {{ssm:/mr2/cloudwatch-custom}}"]"
答え2
正しく引用された行は次のようになります。
$ echo \*/2\ \*\ \*\ \*\ \*\ /usr/bin/aws\ ssm-send-command\ --document-name\ \"AWS-RunShellScript\"\ --parameters\ \'\{\"commands\":\[\"echo\ \{\{ssm:/mr2/cloudwatch-custom\}\}\"\]\"\}\'\ --instance-ids\ \"\$INSTANCE_ID\"\ --region\ us-east-1
もちろん、私がこのような言葉にならない引用文を直接思い出したのではなく、%q
指定子を使用する次のスクリプトを使用しました。
#!/usr/bin/env sh
read
printf "%q\n" "$REPLY" | tr '\n' ' '
答え3
2つの文字列に分割してみてください
echo "*/2 * * * *" /usr/bin/aws ssm-send-command (...) >> /etc/cron.d/lvm_disk_space
これにより、*
ローカルファイル名に拡張されず、残りのパラメータを取得できます。
外部参照が削除されました。
例えば
--document-name "AWS-RunShellScript"
に拡張
--document-name AWS-RunShellScript