`{ echo err >&2; 의 차이점은 무엇인가요? echo>&1; } | :` 및 `{ echo>&1;echo error>&2 } |

`{ echo err >&2; 의 차이점은 무엇인가요? echo>&1; } | :` 및 `{ echo>&1;echo error>&2 } |

명령은 { echo err >&2; echo out >&1; } | :"err"을 인쇄할 수 있는데 두 번째 명령은 인쇄할 수 없는 이유는 무엇입니까?

컨테이너의 일부 테스트:

이는 호스트 CentOS 8.0.1905, Debian 11.4에서도 발생합니다.

~# { echo err >&2; echo out >&1; } | :
err
~# { echo out >&1; echo err >&2; } | :
~#

다음을 사용하지 않는 :것이 올바른 것 같습니다 .

~# { echo out >&1; echo err >&2; } | sed 's/.*/-&-/'
err
-out-
~#

그러나 다른 호스트 CentOS 7.7.1908(bash/4.2.46)에서는 다음과 같이 인쇄됩니다.

~# { echo out >&1; echo err >&2; } | :
err
~#

답변1

사이의 차이

{ echo err >&2; echo out >&1; } | :

... 그리고

{ echo out >&1; echo err >&2; } | :

echo...두 호출이 이루어진 순서입니다. 순서는 진행 방법에 따라 중요합니다.빠르게첫 번째 echo실행이 가능합니다.

파이프의 양쪽은 동시에 시작되며 { ...; }표준 입력 스트림에서 읽지 않습니다. 이는 파이프라인이 종료되자마자 거의 즉시 제거된다는 것을 의미합니다.:::

echo out >&1파이프가 해체되면 쓸 파이프 버퍼가 없습니다 . 존재하지 않는 파이프에 쓰려고 하면 echo파이프의 왼쪽이 PIPE 신호를 받아 죽습니다.

실행 전에 종료 되면 echo err >&2출력이 없습니다.

그래서:

  • 파이프 상태는 고려되지 않으므로 항상 err출력을 얻게 됩니다 .{ echo err >&2; echo out >&1; } | :echo err >&2

  • err때로는 다음과 같은 결과가 출력됩니다.{ echo out >&1; echo err >&2; } | : ~에 따르면:이전에 종료된 경우에도 echo out >&1실행할 수 있는 기회가 있습니다. 먼저 종료 되면 :왼쪽이 조기에 종료되므로 출력이 없습니다.

내 생각에는 대부분의 사람들이 대부분의 시스템에서 두 번째 파이프의 비결정적 동작을 경험하지 않을 것입니다. 그럼에도 불구하고 이를 보여주는 운영 체제와 셸 버전의 조합을 찾을 수 있습니다. 또한 단일 쉘 세션 내에서도 FreeBSD의 비결정적 동작을 복제했습니다 zsh(비록 쉘이 다른 동작보다 한 동작을 선호하는 것처럼 보였지만 마침내 전환을 확인하기까지 10번 더 시도해야 했습니다).

답변2

(우선, 무언가를 시도하고 있는데 그것이 어떻게 작동하고 무엇을 하는지 확신할 수 없다면 로그인한 상태에서 해당 작업을 중단하는 것이 좋습니다 root.)

{ echo err >&2; echo out >&1; } | :

이는 문자열을 에코하고 err\n해당 문자열을 포함하는 표준 출력은 표준 오류(터미널에 표시됨)로 리디렉션된 다음 문자열은 out\n표준 출력으로 에코되어 표준 출력으로 리디렉션됩니다. 그런 다음 표준 출력이 다음으로 파이프됩니다. 표준 입력으로는 :아무것도 출력하지 않습니다.

추가 테스트:

$ { echo err >&2; echo out >&1; } 1> outputfile 2> errorfile
$ for file in *; do echo $file; cat $file; done
errorfile
err
outputfile
out
$ rm  errorfile outputfile
$ { echo err >&2; echo out >&1; } 1> outputfile 2> errorfile
$ for file in *; do echo $file; cat $file; done
errorfile
err
outputfile
out

그렇긴 하지만 어떤 경우에는 표준 오류로 인해 출력이 손실되는 것처럼 보이는 이유가 무엇인지 잘 모르겠습니다. 나는 이것을 재현할 수 없습니다:

$ { echo err >&2; echo out >&1; } | :
err
$ { echo out >&1; echo err >&2; } | :
err

관련 정보