fd3를 사용해도 안전한가요?

fd3를 사용해도 안전한가요?

프로세스 대체를 사용하지 않고 여러 출력 파이프와 같은 작업을 수행하는 데 이를 사용하는 몇 가지 질문이 있습니다.

이를 위해 고정된 fd 번호를 사용하는 것이 안전합니까? 프로그램이 이미 설명된 대로 이를 사용하고 있을 가능성이 있습니까?여기중요한 것을 덮어쓰거나 관련 없는 것을 읽습니까?

답변1

프로그램에서 이미 사용하고 있을 가능성이 있나요?

아니요. 프로그램이나 스크립트가 시작되기 전에 I/O 리디렉션이 발생합니다.

일반적으로 프로그램이나 스크립트가 시작되면 표준 설명자(0/표준 입력, 1/표준 출력, 2/표준 오류)만 열립니다. (터미널, 장치, 파일 또는 네트워크 소켓을 참조할 수 있지만 열려 있을 것으로 예상됩니다. "닫는" 대신 원치 않는 설명자를 에서/로 /dev/null, 본질적으로 "nowhere"/"nothing"으로 리디렉션합니다. .)

open프로그램은 무료 설명자를 사용하는 것과 같은 syscall을 통해 설명자를 사용합니다 . 즉, 커널에 파일이나 소켓을 열도록 요청하지 않습니다.특정 설명자에게, 커널은 설명자를 선택합니다. 따라서 프로그램이 추가 설명자를 사용하는 유일한 경우는 프로그램이 시작될 때 이미 열려 있을 것으로 예상되는 경우입니다. 이와 같은 드문 유틸리티 데몬이 있습니다. 표준 설명자 외에도 설명자 3이 시작될 때 열려 있으면 관리 서비스(또는 이와 유사한 것)에 연결될 것으로 기대합니다.

프로그램이 하드 코딩된 설명자를 사용하기로 결정한 경우(그리고 유일한 이유는 프로그램이 다른 프로그램을 포크하고 실행하기 때문입니다.기대한다해당 설명자는 열려 있어야 합니다. 내가 말했듯이, 이것은 매우 드뭅니다.) 이미 열려 있는 설명자는 프로그램이 그것을 사용하는 다른 것으로 대체할 때 닫힙니다. (그런데 프로그램이 예를 들어 dup2()POSIXy 시스템을 사용하여 특정 설명자를 사용하려고 한다고 나타낼 때 커널은 닫는 작업을 수행합니다. 프로세스는 신경 쓸 필요가 없습니다.)

쉘 스크립트(Bash 및 sh)는 고정된 설명자 번호를 사용하므로 스크립트가 특정 설명자를 사용하여 일부 입력/출력 리디렉션을 수행할 수 있습니다. 그러나 그런 일이 발생하면 스크립트는 설명자가 닫혔다고 가정하기 때문에 이전 리디렉션이 무시되고 아무런 효과도 없습니다. (설명자가 열려 있고 스크립트가 일부 내부 작업에 해당 설명자를 사용하는 경우 스크립트가 이를 리디렉션할 때 이전 단락에서 언급한 이유로 커널에 의해 원래 설명자가 먼저 닫힙니다. 데이터 유출이 발생하려면 스크립트에서 특별히시험설명자가 이미 열려 있는 경우피하다리디렉션합니다.)

또한 Fortran I/O 장치 또는 채널은 식별을 위해 숫자를 사용하더라도 설명자와 관련이 없습니다. 따라서 Fortran 프로그램이 단위 10을 사용한다고 해서 설명자 10을 사용한다는 의미는 아닙니다.

이를 위해 고정된 fd 번호를 사용하는 것이 안전합니까?

예. POSIX에서는 프로그램에 최소 20개의 설명자가 열려 있을 수 있으므로 3에서 19 사이의 고정된 숫자는 모두 잘 작동해야 한다고 말합니다.

핵심은 이를 잘 문서화하는 것입니다. 가급적이면 스크립트 시작 부분(스크립트의 경우)에 있는 짧은 주석이나 사용법( -h또는 --help명령줄 옵션) 및 매뉴얼 페이지(프로그램의 경우)에 기록하는 것이 좋습니다.

스크립트의 경우 충돌이 발생하는 경우(충돌이 발생하면 위에 설명된 대로 "프로그램이 시작되자마자 파이프가 닫히기 때문에 스크립트가 전혀 작동하지 않습니다"라는 오류가 발생함) 사용자가 변경할 수 있다고 가정할 수 있습니다. 필요에 더 잘 맞는 고정 설명자 번호입니다. 따라서 스크립트 작성자로서 귀하의 임무는 미리 계획을 세우고 이후의 사람들이 이를 더 쉽게 만들 수 있도록 하는 것입니다. (의도와 전체적인 디자인을 설명하는 명확한 설명이면 충분합니다. 설명자 번호를 변수로 만들거나 스크립트가 수행하는 모든 작은 작업을 설명할 필요는 없습니다.)

프로그램의 경우 런타임 구성이 가능하도록 만드는 것이 좋습니다. 예를 들어, 프로그램/데몬이 열려 있는 경우 그래픽 사용자 인터페이스가 있는 특수 제어 프로토콜에 대해 설명자 3을 사용하도록 할 수 있습니다. 그러나 '-c 5'와 같은 일부 명령줄 옵션을 사용하면 명명된 설명자를 사용합니다(또는 지정된 파일, 명명된 파이프 또는 로컬 도메인 소켓과 함께 또는 -c /dev/name사용 ). 이 방법으로 사용자는 스크립트와의 충돌을 쉽게 해결할 수 있습니다.-c named-pipe-c :socketpath

관련 정보