리디렉션되지 않은 파이프에서 stderr를 수신하는 Bash

리디렉션되지 않은 파이프에서 stderr를 수신하는 Bash

먼저 리디렉션하지 않고 호출하면 내부에서 stderr을 수신/리디렉션할 수 있습니까 foo.sh?bar.shfoo.sh | bar.sh

foo.sh

#!/bin/bash
echo "hello world" >&2

bar.sh

#!/bin/bash
sed -Eu 's/world/everyone/g'
user@pc$ ./foo.sh | ./bar.sh
hello world

user@pc$ ./foo.sh 2>&1 | ./bar.sh
hello everyone

bar.sh사용자가 첫 번째 예처럼 실수로 호출하더라도 두 번째 예와 같은 동작을 할 수 있나요?

그런데 foo.sh에 무엇이든 쓸 수 있습니다 stderr. 나는 단지 에서 그것을 받는 방법에 관심이 있을 뿐입니다 bar.sh.

답변1

아이디어는 stderr의 데이터를 필터링하는 것이므로 스트림을 병합하거나 모든 stderr을 잃지 않고 이를 수행하는 더 좋은 방법이 있습니다.my_command 2> >(grep --invert-match secret_regex >&2)

구문 설명:

  • 2>"명령의 다음 단어로 표준 오류 보내기"라고 말합니다.
  • >(some_command)표준으로 보내기 전에 물건을 보내라고 말합니다입력하다명령했다.
  • >&2grep마지막으로 출력을 보냅니다 (라인아니요일치 비밀)표준 오류로 돌아갑니다.

필터링 후 stdout 및 stderr이 그대로 유지되는 방법을 보여주는 예:

$ (echo output; echo error >&2; echo secret >&2) 2> >(grep --invert-match secret >&2)
output
error
$ ((echo output; echo error >&2; echo secret >&2) 2> >(grep --invert-match secret >&2)) 2>/dev/null
output
$ ((echo output; echo error >&2; echo secret >&2) 2> >(grep --invert-match secret >&2)) >/dev/null
error

원래 답변: 호출할 때 쉘이 설정될 때마다 (즉, 두 명령이 실행되기 전) ./foo.sh | ./bar.sh표준 오류가 나타납니다. 표준 오류가 가리키는 곳을 "하이재킹" foo.sh하는 것은 (루트 액세스 없이) 불가능하다고 생각합니다 bar.sh. 이는 큰 보안 허점이 될 수 있기 때문입니다. 악의적인 프로세스는 민감한 정보를 인쇄하는 특정 명령의 출력을 하이재킹할 수 있습니다.

답변2

bash속기를 제공하십시오:

만약에|&사용되면 명령의 표준 오류는 표준 출력 외에 command2의 표준 입력으로 파이프됩니다.2>&1 |

관련 정보