나는 비대화형 스크립트를 많이 작성하고 모든 출력이 로그 파일로 이동하고 화면에는 아무것도 나타나지 않기를 원합니다.
이 문제를 해결하기 위해 나는 다음을 사용했습니다.
#!/bin/bash
exec &> logfile
echo "Step One:"
/some/command/one
echo "Step Two:"
/some/command/two
이것이 합리적인 접근 방식인지 확인하고 싶습니다.
이 접근 방식을 계속 사용하면 큰 단점이나 문제가 발생합니까? 그렇다면 그것이 무엇이고 이를 완화하는 최선의 방법(접근 방식 변경 포함).
답변1
명령 출력을 로그 파일로 리디렉션
비대화형 쉘 스크립트가 모든 명령 출력(오류 메시지 포함)을 로그 파일로 리디렉션하는 것은 표준 관행입니다. cron에 의해 실행되거나 다른 외부 이벤트에 의해 트리거되는 스크립트의 명령 출력을 로깅하는 것은 특히 유용하며 이러한 사용 사례에서는 단점이 없습니다.
내 쉘 스크립트의 대부분은 시작 부분에 다음 줄을 포함합니다.
exec 1>>"$logfile"
exec 2>&1
이러한 리디렉션 명령의 순서는 중요합니다. 첫 번째 명령은 (1) 스트림 exec
에 대한 모든 쓰기를 로그 파일에 추가( )하도록 리디렉션합니다. 두 번째 명령은 (2) 스트림에 대한 모든 쓰기를 현재 (1)이 가리키는 동일한 파일 설명자로 리디렉션합니다. 하나의 파일 설명자만 사용하여 파일에 액세스하면 원하는 순서로 쓰기가 발생합니다.stdout
>>
stderr
stdout
Bash를 사용하는 경우 이러한 명령을 동일한 작업을 수행하는 구조로 결합할 수 있습니다.
exec &>>"$logfile"
스크립트를 실행할 때마다 로그 파일의 이전 항목을 지우려면 단일 >
리디렉션 연산자만 사용하십시오(이전 내용 덮어쓰기).
exec &>"$logfile"
exec
내장 함수를 사용한 입력/출력 리디렉션은 POSIX 정의에 의해 지정됩니다.쉘 명령 언어, exec
내장 기능은 모든 POSIX 호환 셸에서 사용할 수 있습니다.
대화형 셸 실행 시 리디렉션
임시/일회용 대화형 셸 세션에서 표준 출력을 파일로 리디렉션해 볼 수 있습니다. 를 실행한 후에는 이후의 모든 명령이 터미널 대신 터미널 exec 1>outfile
에 출력을 인쇄합니다 .outfile
대화형 셸 세션 내에서 표준 오류 리디렉션을 시도할 수도 있지만 이로 인해 대화형 셸 세션을 사용하기가 매우 어려워질 수 있습니다.
를 실행한 후에는 exec 2>errorfile
다른 명령에 의해 생성된 표준 오류가 예상대로 리디렉션된 오류 파일에 기록됩니다. 그러나 문제는지금부터, 쉘(이 경우 Bash)은 프롬프트를 이 파일에 인쇄하고 명령으로 입력된 모든 텍스트도 이 파일로 리디렉션됩니다. 일부 쉘(예: Bash) 은 에서 수신한 stdin
문자를 에코합니다 stderr
. 예를 들어, dash
쉘 세션의 나머지 부분에서는 아무 것도 터미널로 전송되지 않기 때문에 기본적으로 맹목적으로 작업합니다. 이것은 분명히매우 어렵다셸과 계속 상호작용합니다.
~처럼오리온은 다음을 가리킨다.그리고스캇이 말한다, 이러한 실험을 각각 사용하고 시도하기 전에 기본 설명자 및 파일 설명자에 대한 stdout
참조를 저장할 수 있습니다. 실험을 완료한 후 다음을 실행하여 인쇄를 표준 오류로 복원하고 표준 출력으로 인쇄할 수 있습니다.stderr
exec 3>&1
exec 4>&2
exec 2>&4
exec 1>&3
대화형으로 사용하려면 명령별로 표준 출력 및 표준 오류 스트림을 리디렉션하는 것이 좋습니다.>> outfile 2>&1 command with arguments