모든 출력을 하나의 파일, 디버그 로그 및 터미널로 리디렉션 해야하는 bash 파일이 있습니다. stdout과 stderr을 디버그로 리디렉션하고 스크립트의 모든 명령에 대해 로깅해야합니다.
2>&1 | tee -a $DEBUG
파일의 모든 단일 명령에 대해 추가하고 싶지 않습니다 . 나는 함께 살 수있었습니다 | tee -a $DEBUG
.
나는 이와 같은 일을 할 수있는 방법이 있었음을 기억 exec 2>&1
합니다.
현재 다음과 같은 것을 사용하고 있습니다.
#!/bin/bash
DEBUGLOG=/tmp/debug
exec 2>&1
somecommand | tee -a $DEBUGLOG
somecommand2 | tee -a $DEBUGLOG
somecommand3 | tee -a $DEBUGLOG
그러나 작동하지 않습니다. 누구든지 해결책이 있거나 원인을 설명 할 수 있습니까?
답변
많은 명령을 한 번에 리디렉션하는 솔루션은 다음과 같습니다.
#!/bin/bash
{
somecommand
somecommand2
somecommand3
} 2>&1 | tee -a $DEBUGLOG
원래 솔루션이 작동하지 않는 이유 : exec 2> & 1은 표준 오류 출력을 쉘의 표준 출력으로 리디렉션합니다. 콘솔에서 스크립트를 실행하면 콘솔이됩니다. 명령의 파이프 리디렉션은 명령의 표준 출력 만 리디렉션합니다.
의 관점에서 somecommand
, 표준 출력은 연결된 파이프 tee
로 들어가고 표준 오류는 쉘의 표준 오류와 동일한 파일 / 의사 파일로 들어갑니다. 이것은 쉘의 표준 출력으로 리디렉션됩니다. 콘솔에서 프로그램을 실행하는 경우 콘솔.
그것을 설명하는 한 가지 진정한 방법은 실제로 무슨 일이 일어나는지 보는 것입니다.
터미널에서 쉘을 실행하면 쉘의 원래 환경은 다음과 같습니다.
stdin -> /dev/pts/42
stdout -> /dev/pts/42
stderr -> /dev/pts/42
표준 오류를 표준 출력 ( exec 2>&1
) 으로 리디렉션 하면 기본적으로 아무것도 변경되지 않습니다. 그러나 스크립트의 표준 출력을 파일로 리디렉션하면 다음과 같은 환경이 생깁니다.
stdin -> /dev/pts/42
stdout -> /your/file
stderr -> /dev/pts/42
그런 다음 쉘 표준 오류를 표준 출력으로 리디렉션하면 다음과 같이 끝납니다.
stdin -> /dev/pts/42
stdout -> /your/file
stderr -> /your/file
명령을 실행하면이 환경이 상속됩니다. 명령을 실행하여 티에 파이프하면 명령 환경은 다음과 같습니다.
stdin -> /dev/pts/42
stdout -> pipe:[4242]
stderr -> /your/file
따라서 명령의 표준 오류는 여전히 셸이 표준 오류로 사용하는 방식으로 진행됩니다.
실제로 심볼 링크의 내용을 나열하는 데 /proc/[pid]/fd
사용 ls -l
하여 명령의 환경을 볼 수 있습니다 . 0
여기 의 파일은 표준 입력이고 1
표준 출력이며 2
표준 오류입니다. 명령이 더 많은 파일을 열면 (대부분의 프로그램에서) 파일도 볼 수 있습니다. 프로그램은 또한 표준 입력 / 출력 및 재사용을 재 또는 종료를 선택할 수 0
, 1
및 2
.
답변
스크립트 맨 위에서 다음과 같은 exec를 사용할 수 있습니다.
exec > >(tee "$HOME/somefile.log") 2>&1
예를 들면 다음과 같습니다.
#!/bin/bash -
exec > >(tee "$HOME/somefile.log") 2>&1
echo "$HOME"
echo hi
date
date +%F
echo bye 1>&2
파일 $HOME/somefile.log
과 터미널에 다음과 같이 출력합니다 .
/home/saml
hi
Sun Jan 20 13:54:17 EST 2013
2013-01-20
bye
답변
stderr 및 stdout을 파일에 쓰고 화면에 stderr을 표시하십시오 (stdout에서).
exec 2> >(tee -a -i "$HOME/somefile.log")
exec >> "$HOME/somefile.log"
크론에 유용하므로 우편으로 오류 (및 오류 만)를받을 수 있습니다