bash stdout+stderr을 한 파일로 리디렉션하고 stderr을 다른 파일로 리디렉션합니다.

bash stdout+stderr을 한 파일로 리디렉션하고 stderr을 다른 파일로 리디렉션합니다.

모든 출력을 파일로 리디렉션하고 stderr도 다른 파일로 리디렉션해야 합니다. 이것이 쉬운 일입니까?

이 예에서는 내 명령이 다음과 같다고 가정하겠습니다.

php /tmp/doWork.php

다음을 사용하여 출력을 별도의 파일로 출력할 수 있습니다.

php /tmp/doWork.php 1> /tmp/stdout_file 2> /tmp/stderr_file

기반으로이것,나는 다음을 시도한다:

php /tmp/doWork.php &> /tmp/stdboth_file 2> /tmp/stderr_file

하지만 이것은 단지 stdout과 stderr을 넣기 /tmp/stdboth_file만 하고 /tmp/stderr_file.

답변1

zsh다음 과 zsh같은 특징이 있습니다 multios.

your-cmd 2> stdout+stderr.log >&2 2> stderr.log

fd 2는 두 번 리디렉션되므로 zsh구현에서는 tee이를 내부적으로 두 개의 파일로 보냅니다.

bash(또는 Bourne과 같은 쉘( 여기서 작동하기 위해 zsh비활성화해야 하는 경우 제외 multios)) 을 사용하여 tee다음을 사용하여 수동으로 수행할 수 있습니다.

{ your-cmd 2>&1 >&3 3>&- | tee stderr.log 3>&-; } > stderr+stdout.log 3>&1

your-cmdzsh( . 의 종료 상태가 손실 $pipestatus[1]되더라도 해당 내용이 bash포함 되어 있습니다 "${PIPESTATUS[0]}"(리디렉션이 stderr+stdout.log실패하지 않았다고 가정).

pid 를 기록하려면 your-cmd다음을 수행하세요.

{ sh -ec 'echo "$$" > /var/run/pidfile; exec your-cmd' 2>&1 >&3 3>&- |
   tee stderr.log 3>&-; } > stderr+stdout.log 3>&1

yash그리고 그것은프로세스 리디렉션특징:

your-cmd > stdout+stderr.log 2>(tee stderr.log)

(단, yash명령이 종료될 때까지 기다리지 않으므로 tee다음 명령을 실행할 때까지 로그 파일이 완료되지 않을 수 있습니다.)

비슷한 작업을 수행할 수 있습니다(동일한 주의 사항이 있음).프로세스 교체함께 하세요 :bashzshksh93

{ your-cmd 2> >(tee stderr.log); } > stderr+stdout.log

백그라운드에서 실행하고 PID를 얻으려면:

(exec your-cmd 2> >(tee stderr.log)) > stderr+stdout.log & pid=$!

그리고 rc:

{your-cmd |[2=0] tee stderr.log} > stdout+stderr.log

rc파이프를 사용하면 파이프에 연결된 파일 설명자를 지정할 수 있습니다. 다른 쉘의 경우 왼쪽 명령의 fd 1과 오른쪽 명령의 fd 0은 항상 동일합니다(따라서 파일 설명자를 이동하기 위해 fd 3을 사용하여 위의 작은 춤을 춥니다). 또는 실패할 rc경우 실패가 보고되지만 정확한 숫자는 손실될 수 있습니다.your-cmdtee

관련 정보