내가 작업중 인 bash 스크립트 (Ubuntu 및 OS X에서 실행해야 함)에서 수백 개의 명령 출력을 파일로 리디렉션해야합니다. 모든
것을 추가 &>...
하는 대신 간단히
exec 9>&1
exec 5<>/tmp/some-file.txt
exec 1>&5
지금까지는 훌륭했지만 모든 명령을 반쯤 진행하면서 파일 설명자를 열어 둔 상태에서 지금까지 작성된 모든 내용을 읽어야합니다.
우분투에서 간단하게 할 수 있습니다.
cat /dev/fd/5
또는
tee </dev/fd/5
그러나 OS X에서는 아무것도 인쇄되지 않습니다 (명령은 즉시 종료됩니다).
그러나 less
파일을 사용하면 두 파일 모두에서 내용을 볼 수 있습니다.
사용하여 위의 효과 (두 OS 모두에서 작동)를 얻을 수 있습니다
less /dev/fd/5 | tee
그러나 그것은 해킹처럼 보입니다.
그렇다면 왜 OS X에서 할 수없는 less
것들을 볼 cat
수 있습니까? (또는 모든 BSD 자손이 영향을 받습니까?)
아니면 내가 잘못하고 있습니까?
답변
OS X에서 Linux를 제외하고 지원되는 모든 시스템에서 /dev/fd/x
와 마찬가지로 여는 것은 a를 수행하는 것과 비슷 dup(x)
합니다. 결과 fd는 fd x에서와 동일한 열린 파일 설명을 가리키며 특히 파일 내에서 동일한 오프셋을 갖습니다.
여기서 Linux는 예외입니다. 리눅스에서 /dev/fd/x
에 심볼릭 링크 /proc/self/fd/x
와 /proc/self/fd/x
FD X의 파일 열 수있는 의사 심볼릭 링크입니다. Linux에서 작업을 수행 할 때 오픈 파일 과 동일한 파일에 대한open("/dev/fd/x", somemode)
새로운 오픈 파일 설명 이 표시됩니다 x
. 새로운 fd는 fd x와 관련이 없습니다. 특히, 오프셋은 파일의 시작 부분에 있으며 ( O_APPEND
물론 파일을 여는 경우 제외 ) 모드 (읽기 / 쓰기 / 추가 …)는 fd x의 모드와 다를 수 있습니다. 반대 모드에서 파이프를 열 때 파이프의 다른 쪽 끝과 같이 fd x의 것과는 상당히 다른 것). (즉, open () 할 수없는 소켓에서는 작동하지 않습니다 .)
따라서 Linux에서 할 때
exec 5<> file
echo test >&5
fd 5의 오프셋은 파일의 끝에 있습니다. 당신이 할 경우
cat <&5
당신은 아무것도 얻지 못합니다.
여전히 할 때 :
cat /dev/fd/5
fd 5와 관련이없는 새로운 읽기 전용 fd를 가져 오기 test
때문에 알 수 있습니다 .cat
file
다른 시스템에서는
cat /dev/fd/5
cat
fd 5의 복제 본인 fd를 얻으므로 여전히 파일 끝에 오프셋이 있습니다.
그것이 작동하는 이유는 less
어떤 이유 때문이다 less
을한다 lseek()
(A는 않는 파일의 시작 부분에 그 FD에 lseek(1); lseek(0)
파일이 시크인지 여부를 확인).
여기, 아마도 다른 오프셋을 가지려면 읽기 용 fd와 쓰기 용 fd를 원할 것입니다.
exec 5< file 9>&1 > file
또는 당신이 경우 여전히 파일을 다시, 또는이해야 할 것 lseek()
같은 less
않습니다.
ksh93
그리고 zsh
내장 lseek()
연산자 가있는 유일한 쉘입니다 .
cat <&5 <#((0)) # ksh93
{sysseek 0; cat} <&5 # zsh, zmodload zsh/system to enable that builtin
또는:
cat /dev/fd/5 5<#((0)) # ksh93
sysseek -u 5 0; cat /dev/fd/5 # zsh