bash 스크립트는 매개변수와 함께 명령을 실행하고 전체 명령을 파일에 기록합니다.

bash 스크립트는 매개변수와 함께 명령을 실행하고 전체 명령을 파일에 기록합니다.

명령을 실행하고 이를 파일에 추가하는 일반 스크립트를 원합니다.

내 시도는 다음과 같습니다(라는 실행 파일에 저장됨 ./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

흥미로운 질문입니다. 나는 당신이 원하는 것이 완전히 가능하다고 생각하지 않지만 %qBash 구현에서 사용할 수 있는 형식 지정자를 사용하면 꽤 근접할 수 있습니다.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.

관련 정보