표준 출력을 방해하지 않고 bash -x 출력을 로그 파일로 보냅니다.


12

스크립트를 실행하는 사용자가 볼 수있는 표준 출력을 변경하지 않고 -x 옵션과 함께 bash 스크립트를 실행하여 표시되는 정보를 보내는 방법이 있습니까?

이것은 우리가 자주 사용하는 bash 스크립트에서 구현하고 싶은 디버깅 기능입니다.

매우 감사.

답변:


21

-x의 출력은 stdout이 아닌 stderr로 이동합니다. 그러나 그조차도 문제가 될 수 있습니다. 많은 스크립트가 stderr의 내용에 기능적으로 의존하고 경우에 따라 디버그 및 stderr 스트림을 함께 혼합하는 것이 지저분합니다.

Bash 버전> 4.1은 다른 솔루션을 제공합니다. BASH_XTRACEFD 환경 변수를 사용하면 디버그 스트림을 보내는 데 사용할 파일 설명자를 지정할 수 있습니다. 이것은 파일이나 파이프 또는 다른 유닉스 선이 될 수 있습니다.

# Use FD 19 to capture the debug stream caused by "set -x":
exec 19>/tmp/my-script.log
# Tell bash about it  (there's nothing special about 19, its arbitrary)
export BASH_XTRACEFD=19

# turn on the debug stream:
set -x

# run some commands:
cd /etc
find 
echo "Well, that was fun."

# Close the output:
set +x
exec 19>&-

# See what we got:
cat /tmp/my-script.log

조금 더 성가 시게하면 stdout 및 / 또는 stdin 스트림에서 '티'를 수행하고 디버그 출력으로 인터리브하므로 로그가 더 완벽 해집니다. 이에 대한 자세한 내용은 /programming/3173131/redirect-copy-of-stdout-to-log-file-from-within-bash-script-itself를 참조 하십시오 .

대안에 비해이 방법의 가장 큰 장점은 디버그 출력을 stdout 또는 stderr에 주입하여 스크립트의 동작이 변경 될 위험이 없다는 것입니다.


파일에 사용되지 않는 파일 디스크립터를 찾는 방법에 대해서는 여기도 참조하십시오 .
jarno

파일 디스크립터 (예 : line exec 19>&-) 를 닫아야 합니까? 내 경험상 스크립트가 끝나면 자동으로 닫힙니다.
jarno

1
위에 표시된 코드는 스크립트를 실행 중이거나 스크립트의 길이 등을 가정하지 않습니다.이 스 니펫이 수행하는 작업을 수행하여 스크립트에 넣는 경우 파일 핸들이 스크립트의 끝에서 쉘 전체가 사라져서 닫힙니다. 따라서 해당 사용 사례에서 핸들을 반드시 닫을 필요는 없습니다. 그러나 일반적으로 리소스에 대해 코딩 할 때는 열어 놓은 것을 닫는 것이 좋습니다. 코드는 하우스 키핑이 더 중요 할 수있는 더 큰 컨텍스트에서 사용될 수 있기 때문입니다.
Stabledog

BASH_XTRACEFD를 내보내는 이유는 무엇입니까? 왜 가치를 설정하지 않습니까?
jarno

어쨌든, 파일 디스크립터를 닫는 다른 방법은 BASH_XTRACEFD에 대해 새 값 (예 : 널)을 설정하거나 설정 해제하는 것입니다.
jarno

4

set -x표준 출력으로 아무것도 보내지 않으므로 아무런 문제가 없습니다. 그것이 하는 일은 표준 오류에 쓰는 것이며, 기본적으로 콘솔로 이동합니다.

당신이하고 싶은 것은 stdout을 다음과 같이 다른 파일로 리디렉션하는 것입니다.

/bin/sh -x /my/script/file 2>/my/log/file

1

참조하십시오 man tee.

당신은 그것을 좋아 tee commandname filename하고 그것을 명령 출력을 표시하고 stdout또한 그것을 쓸 것이다 filename.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.