나는 실행 파일이 출력을 생성할 때 출력을 인쇄하여 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 스트림을 가져옵니다.write
fdopen
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을 사용하도록 하십시오.