파이프의 다른 수신자에게 stderr 보내기

파이프의 다른 수신자에게 stderr 보내기

이제 나는 이것을 가지고 있습니다 :

 echo "$run_test" | bash 2>&1 | prepend "r2g-test:" "yellow";

이것이 하는 일은 stdout/stderr의 각 줄 앞에 "r2g-test:"를 추가하는 것입니다. stderr을 stdout으로 보내기 때문에 prepend프로그램은 모두 stdin이기 때문에 차이점을 알지 못합니다.

prependstderr를 다른 인스턴스 로 보내는 방법이 있습니까 tee?

어쩌면 이런 게 있지 않을까요?

 echo "$run_test" | bash 2> $(prepend 'r2g-test:' 'red') | prepend 'r2g-test:' 'yellow';

프로세스 대체를 사용하면 다음과 같이 작동할 수 있습니다.

bash 2> >(prepend 'r2g-test:' 'red')

그러나 지금까지 stderr는 터미널에 나타나지 않습니다.

답변1

run_test먼저 stdout 및 stderr을 생성하는 프로그램을 만들어 보겠습니다 .

$ run_test() { while sleep 0.2; do echo "Out $((++c))"; echo "err$c">&2; done; }

이제 stdout과 stderr을 다른 필터로 보내 보겠습니다. 설치되어 있지 않으므로 동일한 목적 prepend으로 사용하겠습니다 .sed

$ exec 3>&2; { run_test | sed 's/^/stdout: /'; } 2>&1 1>&3 | sed 's/^/stderr: /'
stdout: Out 1
stderr: err1
stdout: Out 2
stderr: err2
stdout: Out 3
stderr: err3

어떻게 작동하나요?

  • exec 3>&2

    그러면 파일 설명자 3이 stderr의 복사본으로 생성됩니다.

  • run_test | sed 's/^/stdout: /'

    이것은 실행되어 표준 출력의 시작 부분에 run_test추가됩니다 .stdout:

  • { run_test | sed 's/^/stdout: /'; } 2>&1 1>&3

    2>&stderr가 다음 파이프로 이동하도록 stderr를 stdout으로 리디렉션합니다. 1>&3터미널에 표시되도록 stdout을 stderr로 리디렉션합니다.

  • { run_test | sed 's/^/stdout: /'; } 2>&1 1>&3 | sed 's/^/stderr: /'

    마지막 파이프는 run_test의 stderr(현재 stdout)을 캡처하여 앞에 추가합니다 stderr:.

프로세스 교체 사용

$ run_test > >(sed 's/^/stdout: /') 2> >(stdbuf -oL sed 's/^/stderr: /' >&2)
stdout: Out 1
stderr: err1
stdout: Out 2
stderr: err2
stdout: Out 3
stderr: err3

위의 내용은 stdbufLinux의 표준을 사용합니다. 다른 운영 체제의 경우 유사한 명령을 찾으십시오.

관련 정보