![bash 스크립트는 매개변수와 함께 명령을 실행하고 전체 명령을 파일에 기록합니다.](https://linux55.com/image/160132/bash%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%8A%94%20%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98%EC%99%80%20%ED%95%A8%EA%BB%98%20%EB%AA%85%EB%A0%B9%EC%9D%84%20%EC%8B%A4%ED%96%89%ED%95%98%EA%B3%A0%20%EC%A0%84%EC%B2%B4%20%EB%AA%85%EB%A0%B9%EC%9D%84%20%ED%8C%8C%EC%9D%BC%EC%97%90%20%EA%B8%B0%EB%A1%9D%ED%95%A9%EB%8B%88%EB%8B%A4..png)
명령을 실행하고 이를 파일에 추가하는 일반 스크립트를 원합니다.
내 시도는 다음과 같습니다(라는 실행 파일에 저장됨 ./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.