>

파일 디스크립터 6에서 읽으려면 <&6 를 사용할 수 있습니다  또는 </dev/fd/6  (일명 /proc/self/fd/6 ). 일반적으로 둘 다 동일하게 작동합니다. 그러나 해당 파일 설명자가 소켓이면 이상한 일이 발생합니다. 예를 들면 다음과 같습니다.

$ bash -c 'ls -l /dev/fd/6;cat /dev/fd/6' 6</dev/tcp/localhost/12345
lrwx------ 1 michas michas 64 Jan 10 19:50 /dev/fd/6 -> socket:[315010]
cat: /dev/fd/6: No such device or address

여기 ls  설명자가 실제로 존재 함을 나타냅니다. 그러나이 방법으로는 데이터에 액세스 할 수 없습니다. cat <&6 를 사용하면  대신 모든 것이 다시 잘 작동합니다.

파일 디스크립터에 액세스하는 두 가지 방법의 차이점은 무엇입니까?

변수에 숫자가 주어진 경우 디스크립터에 액세스하는 좋은 방법이 있습니까? (와이즈 와이즈)  작동하지만 </dev/fd/$fd  그렇지 않습니다.)

(위 상황은 리눅스에서는 볼 수 있지만 OpenBSD에서는 볼 수 없습니다.-파일 디스크립터는 일반적인 문자 장치 인 것 같습니다.)

<&$fd
  • 답변 # 1

    /dev/fd/ 에서 읽었 기 때문에  소켓을 나타내는 항목은 Linux에서 구현되지 않습니다. 여기에서 추론에 대한 꽤 좋은 글을 찾을 수 있습니다. 그래서 당신은 stat 를 호출 할 수 있습니다  링크에서, 그래서 당신은 ls 와 함께 그것을 보는 이유입니다 이지만 액세스는 의도적으로 허용되지 않습니다.

    이제 두 번째 부분-왜 bash -c 'ls -l /dev/fd/6; cat <&6' 6</dev/tcp/localhost/12345  작업? /proc 가 아닌 소켓/파일 API를 사용하여 소켓을 읽었 기 때문입니다.  파일 시스템. 이것이 내가 관찰 한 것입니다 :

    <올>

    bash  터미널에서 실행중인 인스턴스는 fd 6으로 소켓을 만듭니다.

    어린이 bash  실행하고 dup2(6, 0) 를 호출 소켓을 cat 로 연결하려면 stdin .

    dup2 인 경우  전화가 실패하지 않았다, 고양이 stdin 에서 읽습니다 .

    다음을 통해 재현하고 관찰 할 수 있습니다 :

    netcat -lp 12345    # in another terminal session (GNU netcat)
    strace -f -e trace=open,read,write,dup2 bash -c 'ls -l /dev/fd/6; cat <&6' \
     6</dev/tcp/localhost/12345
    
    

    bash 가 궁금하십니까?  자식 프로세스는 fd 6에 액세스 할 수 있습니다-파일 디스크립터는 fork 를 유지합니다. , exec 에서 폐쇄 표시되지 않은 경우 , 그들은 거기에서도 닫히지 않습니다.

  • 답변 # 2

    직접적인 질문에 대답하기 위해, "차이는 무엇인가요?":

    <&6 에서 리디렉션 할 때 쉘은 dup2() 를 사용합니다.  파일 디스크립터를 복제하기위한 시스템 호출. </dev/fd/6 에서 리디렉션하려고 할 때 open() 를 사용합니다. .

    커널은 open() 를 지원하지 않습니다   /dev/fd 의 소켓에 ;그것들은장식정보 디렉토리에만 존재합니다.

관련 자료

  • 이전 linux - Fabric을 사용하여 모든 서버에서 명령 실행
  • 다음 더 이상 필요없는 데비안 패키지 그룹을 제거하는 방법은 무엇입니까?