Bash를 사용하여 stderr 및 stdout을 로그 파일에 복사하고 콘솔에 표시하려면 어떻게 해야 합니까?
exec를 사용하여 스크립트 자체에서 이 작업을 수행하고 싶습니다.
나는 전에 시도했다
exec &>> log.out
echo "This is stdout"
echo "This is stderr" >&2
그러나 위의 내용은 콘솔에 아무것도 인쇄하지 않습니다. Bash에서 어떻게 이를 달성할 수 있나요?
답변1
당신이 찾고있는 tee
.
man tee
자세히보다.
그것을 결합 exec
하려면프로세스 교체. ( man bash
자세히보다.)
exec &> >(tee log.out)
echo "This is stdout"
echo "This is stderr" >&2
답변2
이 게시물이 오래된 게시물이라는 것을 알고 있지만 이렇게 하면 어떨까요?
echo "hi" >> log.txt #stdout -> log
echo "hi" | tee -a log.txt #stdout -> log & stdout
echo "hi" &>> log.txt #stdout & stderr -> log
echo "hi" |& tee -a log.txt #stdout & stderr -> log & stdout
물론, stdout을 원한다면 주기적으로 인쇄할 수도 있습니다.
원하는 스트림 조합으로 이 작업을 수행할 수 있습니다. 다음 두 가지 기본 명령을 사용하면 됩니다.
이해하기 쉽고 구현하기 쉬운 답변을 가지고 여기에 오지 않았다는 것을 알고 있습니다. 이것이 다른 사람에게 도움이 되기를 바랍니다.
그런데, 나와 같은 멍청한 놈의 경우 명령이 tee
수행하는 모든 작업은 stdin 입력을 stdout으로 출력하고 파일을 후속 인수로 지정하는 것입니다. -a
추가를 의미하므로 명령을 사용할 때마다 파일을 덮어쓰지 않습니다. 제가 찾은 추가 질문이 있으면이것Bash를 빠르게 배우는 데 매우 유용한 리소스가 됩니다.
답변3
넌 할 수있어:
: > log # empty log file if necessary
{ { {
...the script
} 3>&- | tee -a log >&3 3>&-
exit "${PIPESTATUS[0]}"
} 2>&1 | tee -a log >&2 3>&-
} 3>&1
exit "${PIPESTATUS[0]}"
다음과 같이 작성할 수도 있습니다.
: > log # empty log file if necessary
exec 2> >(tee -a log >&2) > >(tee -a log)
...the script
그러나 bash는 )로 시작하는 프로세스를 기다리지 않기 때문에 >(...
때때로 명령이 반환된 후 터미널에 무언가를 출력하는데, 이는 불쾌한 영향을 미칠 수 있으며 터미널의 "tostop" 속성( 예를 들어 이 출력을 자동으로 삭제하는 것이 켜져 있습니다.
어쨌든 stdout
두 솔루션 모두에서 파이프를 생성하고 두 명령이 출력과 오류 메시지를 독립적으로 출력하므로 이는 출력 버퍼링과 출력 및 오류 메시지가 표시되는 순서에 영향을 미칩니다.
답변4
또 다른 방법은 함수 내에서 리디렉션을 사용하는 것입니다.
#!/bin/bash
function1 () {
echo 'STDOUT from function 1'
echo 'STDERR from function 1' >&2
}
function2 () {
echo 'STDOUT from function 2'
echo 'STDERR from function 2' >&2
}
function3 () {
echo 'STDOUT from function 3'
echo 'STDERR from function 3' >&2
}
main() {
function1
function2
function3
}
main 2>&1 |tee log.txt
main
여기에는 다른 모든 함수를 호출하는 함수가 있습니다 . 이제 STDOUT
및 기능을 로 STDERR
리디렉션합니다 .main
tee