set -x
나는 무슨 일이 일어나고 있는지 보여주기 위해 스크립트에서 이것을 사용하는 것을 좋아합니다 . 특히 스크립트가 CI/CD 파이프라인에서 실행되고 사실 이후에 일부 오류를 디버그해야 할 수도 있는 경우에는 더욱 그렇습니다.
이것에 대한 한 가지 성가신 점은 일부 텍스트(예: 상태 메시지 등)를 사용자에게 다시 에코하려는 경우 "I'm starting to do $X"
해당 메시지가 두 번 출력된다는 것입니다. 한 번은 echo
명령 자체를 에코하고 한 번은 echo
해당 명령의 출력으로 출력됩니다.
이것을 더 좋게 만들 수 있는 좋은 방법이 있나요? 한 가지 해결책은 다음과 같습니다.
set -x
... bunch of normal commands that get echoed
(
# Temporarily don't echo, so we don't double-echo
set +x
echo "Here is my status message"
)
... rest of commands get echoed again
하지만 이렇게 하면 두 가지 문제가 발생합니다.
- 사용자에게 무언가를 말하고 싶을 때마다 작성해야 할 양이 많고, 매번 설명이 필요할 정도로 "명백하지" 않습니다.
set +x
또한 이는 바람직하지 않다는 점을 반영합니다 .
잘 작동하는 다른 옵션이 있습니까?
그것은 마치@
Make의 기능은 에코를 억제하기 위해 앞에 를 추가하는 것입니다.그러면 좋겠지만 Bash에서는 그런 기능을 찾을 수 없었습니다.
답변1
Bash에서 다음과 같이 이를 달성할 수 있습니다.아니요set -x
캡처 대신 사용 DEBUG
하고 자체 추적을 수행하십시오.
#!/bin/bash
set -T
trap '! [[ "$BASH_COMMAND" =~ ^(echo|printf) ]] &&
printf "+ %s\n" "$BASH_COMMAND"' DEBUG
foo=bar
echo This is a test
echo $foo
[[ $foo = bar ]] && /usr/bin/printf 'Matched\n'
아이디어는 해당 줄의 정규식에 무시하려는 명령을 추가하는 것입니다 trap
. 위의 명령을 실행하면 다음이 생성됩니다.
+ foo=bar
This is a test
bar
+ [[ $foo = bar ]]
+ /usr/bin/printf 'Matched\n'
Matched
set -T
트랩이 쉘 함수에 의해 상속되는지 확인하십시오.
트랩을 활성화 및 비활성화하는 별도의 메커니즘을 추가할 수 있습니다.예를 들어쉘 변수를 사용하십시오:
#!/bin/bash
set -T
status() {
NOTRACE=1 echo "$@"
}
trap '! [[ "$BASH_COMMAND" =~ ^(status|NOTRACE=) ]] &&
printf "+ %s\n" "$BASH_COMMAND"' DEBUG
foo=bar
test=$(echo baz)
echo This is a test
status This is a status report
echo $foo
[[ $foo = bar ]] && /usr/bin/printf 'Matched\n'
이것은 생산할 것입니다
+ foo=bar
+ test=$(echo baz)
+ echo This is a test
This is a test
This is a status report
+ echo $foo
bar
+ [[ $foo = bar ]]
+ /usr/bin/printf 'Matched\n'
Matched
답변2
그것은 끔찍한 크루거이고 그것을 제안하는 것이 더럽다고 느껴지지만... 당신은 사용할 수 있습니다마법의 별칭. 이 트릭의 핵심은 별칭이 명령 실행의 구문 분석 단계의 일부로 확장되므로 set -x
함수와 달리 확장 시 아무것도 인쇄되지 않는다는 것입니다. 따라서 별칭을 만들고 명령 앞에 "close -x
" 상용구를 추가한 다음 마지막에 "reopen" 상용구를 실행하는 echo
함수도 필요하다는 것을 발견할 수 있습니다 .-x
또한 스크립트에서 별칭 확장을 활성화해야 합니다. 일반적으로 비활성화되어 있으므로 예를 들어 grep
별칭과 같은 것이 있으면 grep --color
스크립트에서 사용할 때마다 색상 코드가 무작위로 삽입되지 않습니다 grep
. 따라서 가장 안전한 방법은 unalias -a
먼저 실행하여 문제를 일으킬 수 있는 별칭을 제거하는 것입니다.
어쨌든 코드는 다음과 같습니다.
unalias -a
shopt -s expand_aliases
alias cleanecho='{ set +x; } 2>/dev/null; resetx_after echo'
resetx_after() { "$@"; set -x; }
set -x
cleanecho "Ha, ha, you can't see the command that printed this!"
작동 방식: 유사한 명령이 다음 cleanecho "something"
으로 확장됩니다.
{ set +x; } 2>/dev/null; resetx_after echo "something"
{ set +x; } 2>/dev/null
꺼짐 -x
모드(자체 추적을 /dev/null로 리디렉션) 그런 다음 resetx_after echo "something"
다음을 실행하고 실행합니다.
{ echo "something"; set -x; }
...문자열을 인쇄한 다음 -x
추적을 다시 켜세요.
그런데 다른 명령도 비슷하게 사용하려면 printf
비슷한 별칭을 추가하면 됩니다.
alias cleanprintf='{ set +x; } 2>/dev/null; resetx_after printf'
...또는 접두사로 사용할 일반적인 don-trace-this 별칭을 만듭니다.
alias notrace='{ set +x; } 2>/dev/null; resetx_after'
notrace printf 'set -x disabled for this command\n'
답변3
단순한. 이미 절반쯤 왔으니 그냥 set -x
동네 로 이사가세요
#!/bin/sh
echo a
(
set -x
echo b
)
echo c
$ a.sh
a
+ echo b
b
c
스크립트의 일부를 추적하고 싶지 않다면 두 부분으로 나누어 추적하세요.
#!/bin/sh
echo a
(
set -x
echo b
)
echo c
(
set -x
echo d
)
echo e
전체 스크립트보다는 의심되는 부분만 추적하세요.