stdin, stdout 및 stderr 이외의 파일 설명자를 어떻게 얻나요($program 1>file_1 3>file_2와 같은 작업 수행)?

stdin, stdout 및 stderr 이외의 파일 설명자를 어떻게 얻나요($program 1>file_1 3>file_2와 같은 작업 수행)?

나는 실행 파일이 출력을 생성할 때 출력을 인쇄하여 stdout파일로 리디렉션하고 다른 명령으로 파이프할 수 있도록 하는 것을 선호합니다.

실행 파일이 일반적으로 두 개의 다른 파일로 리디렉션되는 두 개의 서로 다른 출력을 작성해야 한다고 가정합니다. 파일 이름을 실행 파일에 전달하는 것을 피하고 파일에 직접 쓰고 싶습니다. 대신 다음과 같은 것을 쓰고 싶습니다.

$ program 1>file_1 3>file_2

비슷한 일을 할 수 있습니까?

답변1

할 수는 있지만 좋은 생각은 아닙니다. 일반적으로 프로그램은 세 개의 파일 설명자가 열린 상태로 시작됩니다.

  • 0은 표준 입력으로, 어떤 방식으로든 텍스트를 처리하는 명령이 입력이 파일에서 나오지 않는 경우 입력을 읽습니다.
  • 1은 표준 출력으로, 명령으로 생성된 일반 데이터에 적합합니다(데이터가 명시적으로 파일로 전송되지 않은 경우).
  • 2는 명령으로 생성된 유용한 데이터의 일부가 아닌 진단 메시지에 대한 표준 오류입니다.

이러한 규칙을 위반하고 더 많은 파일 설명자를 사용할 수 있지만 이는 호출자가 올바른 파일 설명자를 지정한 환경에서만 애플리케이션을 직접 사용할 수 있음을 의미합니다. 애플리케이션에서 이를 쉽게 테스트할 수 없습니다. 파일 설명자 3 이상은 감독되지 않으므로 애플리케이션이 시작될 때 닫힐 수도 있고(감지 가능) 관련 없는 목적으로 열릴 수도 있습니다(감지할 수 없음). ).

명령줄에서 파일 이름을 전달하는 것은 여러 입력 또는 출력 파일을 지정하는 일반적인 방법입니다.

즉, 임의의 파일 설명자에 액세스하려면 다음을 수행하십시오.

  • 쉘에서: 원하는 번호로 리디렉션합니다. 예:

    IFS= read -r line <&3
    printf "%s\n" "$line" >&4
    
  • C에서는 원하는 fd를 호출 read하거나 사용하거나 호출 하여 stdio 스트림을 가져옵니다.writefdopen
  • Perl에서는 파일 설명자를 복사하기 위해 열 파일 이름으로 쉘 리디렉션을 지정하거나 =일반 fdopen.

    open IN3, "<&=3";
    open OUT4, ">&=4";
    
  • Python에서는 os.fdopen.

답변2

예, 물론 가능합니다. 이는 기본값이 1 1>file_1로 단순화된다는 점에 유의하세요 .>file_1

예를 들어:

$ cat test.ksh
#!/bin/ksh
echo "this goes to stdout" 
echo "this goes to stderr" >&2
echo "this goes to fd 3" >&3
$ ./test.ksh >file_1 3>file_2
this goes to stderr
$ cat file_1
this goes to stdout
$ cat file_2
this goes to fd 3

답변3

예제에 표시된 대로 정확하게 셸에서 임의의 파일 설명자를 리디렉션할 수 있습니다. 여러 스트림을 사용하는 프로그램에는 사용할 파일 이름을 알려주어야 합니다. 프로그램이 쉘을 통해(아마도 파이프로) 리디렉션한 fd를 사용하도록 하려면 /dev/fd/N이를 파일 이름으로 전달하여 fd N을 사용하도록 하십시오.

관련 정보