..png)
나는 이 질문에 대한 답을 찾으려고 노력했지만 지금까지는 운이 없었습니다.
다른 스크립트를 실행하는 스크립트가 있는데 그 중 다수에는 실행하는 모든 명령을 인쇄하도록 하는 "set -x"가 있습니다. 나는 그것을 제거하고 싶지만 스크립트가 stderr에 오류 메시지를 보내는 경우 정보를 유지합니다.
그래서 그냥 쓸 수가 없어요 ./script 2>/dev/null
또한, 다른 스크립트를 편집할 수 있는 권한이 없기 때문에 설정 옵션을 수동으로 변경할 수 없습니다.
stderr부터 별도의 파일까지 모든 것을 기록하고 추적 명령을 필터링할 생각인데 더 쉬운 방법이 있을까요?
답변1
버전 4.1 이상 에서는 bash
다음을 수행할 수 있습니다.
BASH_XTRACEFD=7 ./script.bash 7> /dev/null
bash
(콜로 호출된 경우에도 유효합니다 sh
.)
기본적으로 출력이 기본값 2 대신 파일 설명자 7에 bash
기록되도록 지시 xtrace
하고 해당 파일 설명자를 로 리디렉션합니다 /dev/null
. fd 번호는 임의적입니다. 스크립트에서 사용되지 않는 2보다 큰 fd를 사용하십시오. 이 명령을 입력한 쉘이 bash
또는 인 경우 yash
9보다 큰 숫자를 사용할 수도 있습니다(파일 설명자가 쉘에서 내부적으로 사용되는 경우 문제가 발생할 수 있음).
스크립트를 호출하는 쉘이 이면 bash
다음 zsh
을 수행할 수도 있습니다.
(export BASH_XTRACEFD; ./script.bash {BASH_XTRACEFD}> /dev/null)
9를 초과하는 첫 번째 여유 fd는 자동으로 변수에 할당됩니다.
이전 버전의 경우 bash
또 다른 옵션은 xtrace
전달 시 아무 작업도 수행하지 않는 내보낸 함수로 재정의하는 것입니다(단, 위치 매개변수를 설정하는 데 사용되는 경우(또는 다른 스크립트를 호출하는 경우) 스크립트가 중단됩니다.)set -x
#! /bin/bash -x
set -o xtrace
set
-x
bash
set
좋다:
set()
case $1 in
(-x) return 0;;
(-[!-]|"") builtin set "$@";;
(*) echo >&2 That was a bad idea, try something else; builtin set "$@";;
esac
export -f set
./script.bash
$BASH_ENV
또 다른 옵션은 각 명령 전에 실행되는 파일에 DEBUG 트랩을 추가하는 것입니다 .set +x
echo 'trap "{ set +x; } 2>/dev/null" DEBUG' > ~/.no-xtrace
BASH_ENV=~/.no-xtrace ./script.bash
set -x
그러나 이는 서브쉘에서 수행되면 작동하지 않습니다.
@ilkkachu가 말했듯이 파일 시스템의 모든 폴더에 대한 쓰기 권한이 있는 한 최소한 스크립트를 복사하고 편집할 수 있어야 합니다.
스크립트 복사본을 작성할 곳이 없거나 원본 스크립트를 업데이트할 때마다 새 복사본을 만들고 편집하는 것이 불편한 경우에도 다음을 수행할 수 있습니다.
bash <(sed 's/set -x/set +x/g' ./script.bash)
$0
스크립트가 화려하거나 특별한 작업(예: 스크립트 자체의 위치를 기준으로 파일 찾기)을 수행하는 경우 이 $BASH_SOURCE
방법(및 복사 방법)이 제대로 작동하지 않을 수 있으므로 $0
스크립트 경로 ...
답변2
스크립트이기 때문에할 수 있다복사하고 편집하세요.
그 외에 출력 필터링은 간단해 보이며 PS4
단일 더하기 기호보다 더 특이한 것으로 명시적으로 설정하여 필터링을 더 쉽게 만들 수 있습니다.
PS4="%%%%" bash script.sh 2>&1 | grep -ve '^%%%%'
(물론 이렇게 하면 stdout과 stdin이 충돌하지만 Bash에서 stderr을 파이핑하는 것은 약간 번거롭기 때문에 무시하겠습니다)