오류를 파일로 리디렉션하는 방법은 무엇입니까?

오류를 파일로 리디렉션하는 방법은 무엇입니까?

append출력을 파일로 리디렉션하는 간단한 스크립트가 있습니다 .

filename="/home/ronnie/tmp/hello"

date=$(date)
echo "$date" >> $filename

이제 오류를 생성 date=$(date)하도록 변경했다고 가정해 보겠습니다 .date= $(date)

내 수정된 스크립트:

filename="/home/ronnie/tmp/hello"

date= $(date)
echo "$date" >> $filename 2>> $filename 
#Also tried echo "$date" >> $filename 2>&1

위 스크립트가 오류를 test.sh: line 5: Fri: command not found파일로 리디렉션할 것이라고 생각했지만 hello파일에 새 줄을 추가하고 오류가 내 stdout.

내 배쉬 버전:

ronnier@ronnie:~/tmp$ bash --version
GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu)

그래서 내가 어디로 잘못 갔나요?

답변1

오류를 일으키는 줄은 date =$(date)오류가 stderr로 전송된다는 것입니다. 이 단계에서는 stderr를 어디로도 리디렉션하지 않습니다. 후속 라인은 stderr을 $filename으로 보내지만 이는 오류를 일으키는 라인이 아닙니다.

원하는 효과를 얻는 한 가지 방법은 스크립트를 실행하고 stderr를 다른 곳으로 보내는 것입니다.

./myscript 2>> errors.txt

이 시점에서 error.txt에는 오류가 포함됩니다.

따라서 문제는 오류를 생성하는 줄이 스크립트 자체의 오류이지 출력이 리디렉션되는 스크립트에서 호출한 외부 명령으로 인해 발생한 오류가 아니라는 것입니다. 즉, 리디렉션해야 하는 최상위 스크립트 출력입니다.

답변2

쉘은 라인 5에 도달하면 오류 메시지를 발행합니다. 현재 쉘의 오류 스트림은 리디렉션되지 않습니다.

을 쓰면 date= $(date) 2>/dev/null"명령을 찾을 수 없음" 메시지가 오류 스트림이 리디렉션되는 명령이 아닌 셸에서 나타납니다. 따라서 여전히 오류 메시지가 표시됩니다.

오류 메시지가 표시되지 않도록 하려면 전체 명령을 그룹에 넣고 전체 그룹에서 오류 흐름을 리디렉션하세요.

{ date= $(date); } 2>/dev/null

중괄호를 사용하는 경우 명령은 여전히 ​​상위 셸에서 실행되므로 환경 및 기타 상태를 변경할 수 있습니다(여기에서는 실행되지 않음). 함수 본문이나 하위 셸에 명령을 넣을 수도 있습니다(괄호로 묶인 명령은 별도의 셸 프로세스에서 실행됩니다).

exec명령 이름 없이 내장 명령에 대한 리디렉션을 사용하여 쉘의 파일 설명자를 영구적으로(또는 적어도 다음에 변경할 때까지) 리디렉션할 수 있습니다.

exec 2>/dev/null
# From this point on, all error messages are lost
date= $(date)
exec 2>/some/log/file
# From this point on, all error messages go to the specified file

관련 정보