쉘 스크립트의 출력을 리디렉션했을 때 다소 이상한 동작을 발견했습니다. 스크립트 자체가 일부 출력을 /dev/stdout 또는 /dev/stderr로 리디렉션했습니다.
쉘 스크립트
$ cat test.sh
#!/bin/bash -x
echo stdout
echo stderr >&2
echo '/dev/stdout' > /dev/stdout
echo '/dev/stderr' > /dev/stderr
기준: 리디렉션 없음
$ ./test.sh
+ echo stdout
stdout
+ echo stderr
stderr
+ echo /dev/stdout
/dev/stdout
+ echo /dev/stderr
/dev/stderr
리디렉션을 수행하지 않으면 모든 것이 예상대로 나타납니다.
표준 출력 리디렉션
$ ./test.sh > out
+ echo stdout
+ echo stderr
stderr
+ echo /dev/stdout
+ echo /dev/stderr
/dev/stderr
$ cat out
/dev/stdout
stdout을 리디렉션하면 "/dev/stdout" 줄이 예상대로 리디렉션되지만 "stdout" 줄은 더 이상 어디에도 나타나지 않습니다.
스트림을 별도의 파일로 리디렉션
$ ./test.sh > out 2> err
$ cat out
/dev/stdout
$ cat err
/dev/stderr
"stderr"뿐만 아니라 "bash -x" 줄도 사라졌습니다.
스트림을 동일한 파일로 리디렉션
$ ./test.sh > out 2>&1
$ cat out
/dev/stderr
마지막 경우에는 이전 예제의 모든 내용이 손실되고 이전에 파일로 성공적으로 리디렉션된 "/dev/stdout"도 손실됩니다.
예를 들어 셸 스크립트에서 exec 줄을 사용하여 리디렉션하면 exec 1>out; exec 2>&1;
명령줄에서 리디렉션하는 것과 동일한 동작이 발생합니다.
질문: 누락된 줄이 누락되는 이유는 무엇이며, 이러한 일이 발생하도록 스크립트의 모든 줄(명령줄 리디렉션을 통해 실행된 암시적으로 실행된 줄 포함)에 어떤 일이 발생합니까? 바람직하게는 후자의 답변이 관련된 시스템 호출(dup2?)을 설명합니다.
답변1
파일로 리디렉션 중이기 때문에
echo '/dev/stdout' > /dev/stdout
echo '/dev/stderr' > /dev/stderr
파일에 추가하지 않고 덮어씁니다. 리디렉션하지 않으면 stdout/stderr에만 추가할 수 있으므로 이 사실을 알 수 없습니다.
사용. . . 교체
echo '/dev/stdout' >> /dev/stdout
echo '/dev/stderr' >> /dev/stderr
모든 것이 정상으로 돌아왔습니다.