![cron.d에 대한 에코 명령](https://linux55.com/image/165915/cron.d%EC%97%90%20%EB%8C%80%ED%95%9C%20%EC%97%90%EC%BD%94%20%EB%AA%85%EB%A0%B9.png)
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
첫 번째 명령의 문제점은 *
문자가 인용되지 않는다는 것입니다. 따라서 쉘은 이를 현재 디렉토리에서 일치하는 파일 이름으로 확장합니다.
두 번째 명령의 문제점은 작은 따옴표와 큰 따옴표가 모두 포함되어 있으므로 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
두 개의 문자열로 분할해 보세요
echo "*/2 * * * *" /usr/bin/aws ssm-send-command (...) >> /etc/cron.d/lvm_disk_space
이렇게 하면 *
로컬 파일 이름으로 확장되지 않고 나머지 매개변수를 얻을 수 있습니다.
외부 참조가 제거되었습니다.
예를 들어
--document-name "AWS-RunShellScript"
로 확장됩니다
--document-name AWS-RunShellScript