stdout 및 stderr을 파일로 리디렉션하고 stderr을 콘솔에 표시하는 방법은 무엇입니까? # redirect stderr to a file, display

파일로 리디렉션하고 tee를 사용하는 방법을 알고 있습니다. 기본 수준에서. 그래서

$ alias outanderr='bash -c "echo stdout >&1; echo stderr >&2"'
# A fake "application" displaying both output and error messages.

$ outanderr 1>file      # redirect stdout to a file, display stderr
stderr

$ outanderr 2>file      # redirect stderr to a file, display stdout
stdout

$ outanderr 1>file 2>&1 # redirect both to a file, display nothing

$ outanderr | tee file; echo "-- file contents --" && cat file
# redirect stdout to a file, display both (note: order is messed up)
stderr
stdout
-- file contents --
stdout

$ outanderr 2>&1 | tee file; echo "-- file contents --" && cat file
# redirect both to a file, display both
stdout
stderr
-- file contents --
stdout
stderr

문제는 다음과 같은 결과를 얻기 위해 물음표 대신 무엇을 작성해야 하는가입니다.

$ outanderr ???; echo "-- file contents --" && cat file
# redirect both to a file, display stderr
stderr
-- file contents --
stdout
stderr

포함 :

  • bash를 가정합니다.
  • 순서는 파일에 보관해야합니다.
  • stderr 내용은 실시간으로 표시됩니다 (즉, 버퍼링 없음).
  • 별도의 스크립트 파일을 사용할 수 있습니다.
  • 마술이 필요할 수 있습니다.


답변

2>&1 >>outputfile | tee --append outputfile

쉬운 테스트를 위해 :

echo -n >outputfile; bash -c "echo stdout >&1; echo stderr >&2" 2>&1 >>outputfile |
  tee --append outputfile; echo "outputfile:"; cat outputfile

편집 1 :

이것은 stdout을 파일에 쓰고 sterr stdout이 파이프를 통과하도록 만들고 tee가 출력을 동일한 파일에 쓰도록하여 ​​작동합니다.

두 쓰기는 모두 >>대신 추가 모드에서 수행되어야합니다. >그렇지 않으면 둘 다 서로의 출력을 덮어 씁니다.

파이프가 버퍼이므로 출력이 파일에 올바른 순서로 표시된다는 보장은 없습니다. 응용 프로그램이 두 파일 디스크립터 (파이프 2 개) 모두에 연결된 경우에도 변경되지 않습니다. 순서를 보장하기 위해 두 출력 모두 동일한 채널을 거쳐 각각 표시되어야합니다. 아니면 정말 멋진 것들이 필요할 것입니다.

  1. stdout과 stderr이 모두 동일한 파일이 아닌 파일로 리디렉션되고 두 파일이 모두 FUSE 볼륨에있는 경우 FUSE 모듈은 각 단일 쓰기에 타임 스탬프를 표시하여 두 번째 응용 프로그램이 데이터를 올바르게 정렬하고 결합 할 수 있습니다 실제 출력 파일. 또는 데이터를 표시하지 않지만 모듈이 결합 된 출력 파일을 작성하도록합니다. 아마도이 작업을 수행하는 FUSE 모듈이 아직 없을 것입니다 …
  2. stdout과 stderr 모두에 지시 될 수 있습니다 /dev/null. 를 통해 실행하면 응용 프로그램의 출력이 분리됩니다 strace -f -s 32000 -e trace=write. 이 경우 이스케이프 처리를 취소해야합니다. 말할 필요없이 응용 프로그램이 더 빨리 실행되지는 않습니다.
  3. 기존의 간단한 FUSE 모듈을 사용하고 애플리케이션 대신 모듈을 추적하여 동일한 결과를 얻을 수 있습니다. 모듈은 아마도 응용 프로그램보다 훨씬 적은 syscall을 가지기 때문에 응용 프로그램을 추적하는 것보다 빠릅니다.
  4. 응용 프로그램 자체를 수정할 수있는 경우 : 각 출력 후에 응용 프로그램을 중지 할 수 있지만 (내부에서만 가능하다고 생각) s 신호 (SIGUSR1 또는 SIGCONT)를 수신 한 후에 만 ​​계속할 수 있습니다. 파이프에서 읽는 응용 프로그램은 파이프와 파일 모두에서 새 데이터가 있는지 확인하고 새 데이터마다 신호를 보내야합니다. 응용 프로그램의 종류에 따라 strace 방법보다 빠르거나 느릴 수 있습니다. FUSE가 최대 속도 솔루션입니다.