& 6과 / dev / fd / 6의 차이점은 무엇입니까?


11

파일 디스크립터 6에서 읽으려면 <&6or </dev/fd/6(aka /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작동하지만 <&$fd작동하지 않습니다.)

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


1
이것은 중복 된 것 입니까
cuonglm

2
감사. 관련이 있지만 실제로는 중복되지 않습니다.
michas

답변:


5

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

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

  1. bash 터미널에서 실행되는 인스턴스는 fd 6으로 소켓을 만듭니다.
  2. 아동 bash실행 및 호출 dup2(6, 0),로 소켓을 연결하기 위해 catS ' stdin.
  3. 경우 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자식 프로세스는 6가 fd에 대한 액세스가 - 기술자가 살아 남기 파일을 fork, 그리고 그들에 닫는 표시되지 않은 경우 exec, 그들은뿐만 아니라이 폐쇄되지 않습니다.


3

당신의 직접적인 질문에 대답하기 위해 " 차이는 무엇 입니까?"

에서 리디렉션 <&6하면 셸은 dup2()시스템 호출을 사용 하여 파일 설명자를 복제합니다. 에서 리디렉션을 시도하면를 </dev/fd/6사용 open()합니다.

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.