편집하다
허용되는 답변뿐만 아니라 다른 답변도 참조하십시오.
질문
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