편집하다

편집하다

편집하다

허용되는 답변뿐만 아니라 다른 답변도 참조하십시오.

질문

1>[FILENAME] 2>&1 과 동일해 보이지만 STDOUT 및 STDERR을 동일한 파일로 리디렉션하는 것이 작동하지 않는 이유는 무엇입니까?

예는 다음과 같습니다.

perl -e 'print "1\n" ; warn "2\n";' 1>a.txt 2>a.txt
cat a.txt
# outputs '1' only.

왜요? STDOUT이 a.txt로 리디렉션되고 STDERR도 마찬가지이기 때문에 이것이 작동한다고 생각했습니다. STDERR은 어떻게 됐나요?

답변1

두 리디렉션 모두 파일을 자르므로 두 번째 리디렉션(실행 시간순)이 첫 번째 리디렉션을 덮어씁니다. 노력하다

rm a.txt ; touch a.txt ; perl -e 'print "1\n" ; warn "2\n";' 1>>a.txt 2>>a.txt

아니면 동일한 파일 설명자를 사용하세요.

perl -e 'print "1\n" ; warn "2\n";' 1>a.txt 2>&1

답변2

을 사용하면 1>a.txt 2>&1파일 설명자 #1은 다음과 같습니다.중복됨#2로. 둘 다 동일한 "열린 파일"을 참조하며 둘 다 현재 위치와 r/w 모드를 공유합니다. (실제로 2>&1과 2<&1을 사용하는 것에는 전혀 차이가 없습니다.)

를 사용하면 1>a.txt 2>a.txt두 파일 설명자가 모두독립적으로 오픈별도의 커서 위치가 있습니다. (파일도 두 번 잘립니다.) fd #1에 "Hello"를 쓰면 해당 위치는 byte 5로 이동하지만 fd #2는 byte 0에 남아 있습니다. fd #2에 인쇄하면 0부터 시작하는 데이터를 덮어쓰게 됩니다. .

두 번째 쓰기가 더 짧은지 쉽게 확인할 수 있습니다.

$ perl -e 'STDOUT->print("abcdefg\n"); STDOUT->flush; STDERR->print("123");' >a.txt 2>a.txt

$ cat a.txt 
123defg

Perl에는 내부 버퍼링이 있으므로 이 예에서는 fd #1 데이터가 fd #2 데이터보다 먼저 기록되도록 보장하기 위해 명시적인 플러시()가 필요합니다. 그렇지 않으면 종료 시 스트림이 예측할 수 없는 순서로 플러시됩니다.

비교를 위해 파일 설명자가 공유되면 쓰기가 서로 뒤따릅니다.

$ perl -e 'STDOUT->print("abcdefg\n"); STDOUT->flush; STDERR->print("123");' >a.txt 2>&1

$ cat a.txt 
abcdefg
123

관련 정보