OS X, bash : 열린 파일 디스크립터에서 덜 작동, cat은 추가 &>…하는 대신 간단히 exec 9>&1 exec

내가 작업중 인 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/xFD 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때문에 알 수 있습니다 .catfile

다른 시스템에서는

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


답변