스크립트 외부에서 bash 실행 추적 (set -x)을 억제하십시오.


17

나는이 질문에 대한 답을 찾으려고했지만 지금까지 운이 없었습니다.

나는 다른 스크립트를 실행하는 스크립트를 가지고 있으며, 그 밖의 다른 스크립트는 "set -x"를 가지고있어서 실행하는 모든 명령을 인쇄합니다. 나는 그것을 없애고 싶지만 스크립트 중 하나가 오류 메시지를 stderr에 보내면 정보를 유지하고 싶습니다.

그래서 나는 단순히 쓸 수 없습니다 ./script 2>/dev/null

또한 다른 스크립트를 편집 할 수있는 권한이 없으므로 set 옵션을 수동으로 변경할 수 없습니다.

stderr에서 별도의 파일까지 모든 것을 기록하고 추적 명령을 필터링하는 것에 대해 생각하고 있었지만 더 간단한 방법이 있습니까?


1
./script 2>some_file
Satō Katsura

답변:


25

으로 bash4.1 이상, 당신은 할 수있다

BASH_XTRACEFD=7 ./script.bash 7> /dev/null

bash로 호출 될 때도 작동합니다 sh.

기본적으로 우리는 기본값 2 대신 파일 설명자 7에 bash출력을 출력하고 xtrace해당 파일 설명자를로 리디렉션합니다 /dev/null. fd 번호는 임의입니다. 스크립트에서 다르게 사용되지 않는 2보다 큰 fd를 사용하십시오. 이 명령을 입력하는 셸이 bash또는 yash인 경우 9보다 큰 숫자를 사용할 수도 있습니다 (파일 설명자가 셸에서 내부적으로 사용되는 경우 문제가 발생할 수 있음).

해당 bash스크립트를 호출하는 쉘이 is 인 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스크립트 경로로 바꾸십시오 ...


첫 번째 대답은 내가 필요로하는 것입니다. 깨끗하고 우아합니다. 어떻게 작동하는지 조금 설명해 주시겠습니까? 왜 숫자 7입니까? 다른 숫자는 무엇을 위해 사용될 수 있습니까? 감사.
인간

@human, 편집 참조
Stéphane Chazelas

1
{BASH_XTRACEFD}>트릭은 작동 bash후뿐만 아니라 4.1.
chepner

@ chepner, 예 zsh 개발자가 제안한 기능이 zsh, ksh93 및 bash에 동시에 추가되었습니다. 그러나, 여기에는 대한 작업을하지 않는 ksh93또는 bash변수가 명령 (비교의 환경에 전달되지 않는다는에 <shell> -c 'export fd; printenv fd {fd}> /dev/null'zsh, bash그리고 ksh93). 두 단계로 수행 하거나을 사용하여 ksh93/ 작동하도록 만들 수 있지만 xtrace 옵션이 켜져 있으면 부작용이 생길 수 있습니다. bashevalbash
Stéphane Chazelas

5

그들이 스크립트를 것 때문에, 당신은 할 수 그 사본을 만들고, 편집 그.

그 외에는 출력을 필터링하는 것이 단순 해 보일 PS4수 있으므로 필터링을 쉽게하기 위해 단일 플러스보다 더 특이한 것으로 명시 적으로 설정할 수 있습니다.

PS4="%%%%" bash script.sh 2>&1 | grep -ve '^%%%%'

(물론 stdout과 stdin을 무너 뜨릴 것이지만 Bash의 stderr를 파이핑하면 약간 털이 생겨 무시합니다)


1
stderr 만 배관하는 것은 쉽습니다 PS4="%%%%" bash script.sh 2> >(grep -ve '^%%%%').
Patrick

4
@Patrick 은 비동기식으로 실행 bash되는 문제 grep가 있습니다 (bash는 대기하지 않으므로 스크립트의 다음 명령이 시작된 후 출력 할 수 있습니다 (종종)).
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.