제가 작업 중인 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
파일의 내용은 I를 사용하여 두 가지 모두에서 볼 수 있습니다.
다음을 사용하여 위의 효과(두 OS 모두에서 작동)를 달성할 수 있었습니다.
less /dev/fd/5 | tee
하지만 이건 해킹인 것 같습니다.
less
그렇다면 OS X에서는 볼 수 없는 것을 보는 것이 분명히 가능한 이유는 무엇입니까 ? cat
(아니면 모든 BSD 자손이 영향을 받나요?)
아니면 제가 뭔가 잘못하고 있는 걸까요?
답변1
OS X에서는 이를 지원하는 모든 시스템과 마찬가지로리눅스 제외/dev/fd/x
, a 실행과 마찬가지로 열면 dup(x)
결과 fd는 fd x와 거의 동일한 열린 파일 설명, 특히 파일 내에서 동일한 오프셋을 가리킵니다.
여기서는 Linux는 예외입니다. Linux에서는 /dev/fd/x
fd x 에서 열린 파일에 대한 기호 링크 /proc/self/fd/x
이자 /proc/self/fd/x
의사 기호 링크입니다. Linux에서는 를 실행하면 open("/dev/fd/x", somemode)
완전히 새로운 것을 얻게 됩니다.파일 설명 열기열린 파일과 동일한 파일에 x
. 당신이 얻는 새로운 fd는 fd x와 아무 관련이 없습니다. 특히 오프셋은 파일의 시작 부분에 있습니다(물론 O_APPEND
역방향 모드에서 파이프를 열 때 다른 쪽 끝에서 열지 않는 한 ). (이것은 또한 소켓에서는 작동하지 않는다는 것을 의미합니다.열려 있는()).
따라서 Linux에서는 다음과 같은 작업을 수행할 때
exec 5<> file
echo test >&5
fd 5의 오프셋은 파일 끝에 있습니다. 당신이 그렇게한다면
cat <&5
당신은 아무것도 얻지 못합니다.
또는 다음을 수행할 때:
cat /dev/fd/5
보시다시피 test
, fd 5와 아무 관련이 없는 새로운 읽기 전용 fd가 얻어지기 때문입니다 cat
.file
다른 시스템에서는
cat /dev/fd/5
cat
fd 5와 중복된 fd를 가져오면 파일 끝에 여전히 오프셋이 있습니다.
이것이 작동하는 이유 는 어떤 이유로 a가 less
해당 fd에서 파일 시작 부분까지 less
실행되기 때문입니다(a는 파일을 검색할 수 있는지 확인하기 위해 실행됩니다).lseek()
lseek(1); lseek(0)
여기서 두 fd가 서로 다른 오프셋을 갖도록 하려면 읽기용 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