파일 설명자 2가 읽기 및 쓰기용으로 열려 있습니다.

파일 설명자 2가 읽기 및 쓰기용으로 열려 있습니다.

이것은 stderr에서 읽기 위해 작성한 C 프로그램입니다.

#include <uninstd.h>
#include <stdio.h>

int main(void) {
 char buff[3];
 read(2, buff, sizeof(buff));
 printf("%s", buff");
 return 0;
}

내 질문은 stderr를 보내는 방법입니다. 대부분의 검색은 bash 리디렉션으로 표시됩니다.

command 2> file

그러나 이것은 stderr을 파일로 보냅니다.

내 프로그램에 어떻게 전달할 수 있습니까? 점처럼,

command 2 "somthing here" ./myprogram

답변해 주셔서 감사합니다.

답변1

대부분의 참고서와 문서는 항상 표준 오류를 출력으로 제공하고 실제로는 일반적으로이미 읽기+쓰기용으로 열렸습니다.. 귀하의 프로그램이 매우 마음에 듭니다할 수 있는파일 설명자 2에서 읽습니다.

(참고: 이 답변에서는 실제 파일 설명자 번호를 사용합니다.C 흐름stderr프로그램이 이를 변경할 수 있고 C 스트림의 역할에 대해 말할 때 혼란을 가중시키기 때문에 실제로 이러한 파일 설명자에 대응할 필요는 없습니다 . 귀하의 프로그램은 read(). )

파일 설명자 2가 읽기 및 쓰기용으로 열려 있습니다.

상위 프로세스에서 리디렉션을 사용하지 않는 로그인 세션의 프로그램의 경우 파일 설명자 2(표준 오류)는 일반적으로 파일 설명자 0(표준 입력)의 복사본입니다. 그들은 모두 동일한 기본을 참조합니다.파일 설명, 이는 일반적으로 세션이 로그인되는 터미널입니다( ttymon이전 시스템에서 getty세션 시작 시 열리고 복사됨 ).

파일 설명자 2에서 읽는 경우 파일 설명자 0에서 읽는 것과 동일한 입력을 얻습니다.

/dev/tty참고: 1977년경에 이 장치가 도입되기 전에는 파일 설명자 2에서 읽는 것이 비밀번호 입력과 같은 용도로 자주 사용되었습니다. 파일 설명자 2에서 읽는 이유는 파일 설명자 0이 다른 곳(예: 파이프 중간)으로 리디렉션될 때 원래 터미널에서 입력을 얻기 위한 것입니다.

/dev/ttyPOSIX는 40년이 넘는 오랜 역사를 갖고 있지만 여전히 파일 설명자 2도 읽기 위해 열려 있어야 합니다 .

귀하의 프로그램이 수행하지 않는 작업

파일 설명자 2에서 다른 프로그램의 출력을 읽는 것은 또 다른 문제입니다. 넌 쉽게 할 수 없어그 자체를 통해, 표준 출력과 표준 오류를 병합하지 않습니다. 일반적으로 시리즈 3>&1 1>&2 2>&3또는 유사한 교환이 포함됩니다. 일부 쉘은 다음을 호출하여 출력 파일 설명자 2에 파이프를 허용합니다.

prog1 2| prog2

그러나 그러한 껍질은 드물다.당신의그럼에도 불구하고 프로그램에서는 이를 요구합니다.

프로그램에 입력 보내기

프로그램이 파일 설명자 2에서 읽도록 하려면 다음을 읽을 수 있습니다.다른물론 터미널에서보다 해당 파일 설명자를 리디렉션할 수 있습니다. 너할 수 있다일반 사용입력하다리디렉션 구문( <셸의 연산자)이지만 프로그램의 라이브러리와 심지어 다른 곳에서 작성한 다른 코드도 이 파일 설명자에 쓸 수 있다고 가정합니다.

셸을 사용하면 <>리디렉션 연산자를 사용하여 읽고 쓰기 위해 파일을 명시적으로 열 수 있습니다. 이는 프로그램의 파일 설명자 2를 리디렉션할 때 사용하는 것입니다.

./myprogram 2<>filename

쉘 리디렉션 외에도 파일 설명자를 조작하기 위한 많은 도구가 있습니다. 예: Laurent Bercot의 체인 로딩redirfdexecline과 함께 제공되는 도구는 이 리디렉션이 귀하의 가설과 더 유사해 보입니다.

redirfd -u 2 filename ./myprogram

Bourne Again 및 Z 쉘(Almquist 쉘은 아님)과 같은 쉘 구문도 파일 설명자 2에 대해 "여기에 문서" 및 "여기에 문자열"을 제공합니다. 파일 설명자 2가 열려 있음을 참고하세요.읽기 전용이 경우 이러한 껍질을 통해.

./myprogram 2<<< "here string"

답변2

stderr읽기용이 아닌 쓰기용입니다. 때로는 dup중복되는 경우도 있습니다 stdin(예: 3개의 입력/출력/오류가 모두 터미널에 연결된 경우). 다른 프로그램의 stderr을 읽으려면 해당 프로그램의 stderr를 다른 프로그램의 stdin으로 리디렉션할 수 있습니다.

stdout예를 들어 파일을 가리킨 다음 stderr의 ../myprogramsstdin

command 2>&1 >a_file | ./myprogram

답변3

bashzsh일반 POSIX가 아닌 and 와 같은 쉘을 사용하면 sh한 프로그램의 표준 오류를 다른 프로그램의 표준 입력으로 리디렉션하여 이를 수행할 수 있습니다 firstprogram 2> >(second program).

예:

$ perl -E 'say "perl stdout"; warn "perl stderr\n"' 2> >(awk '{print "awk", $0}')
perl stdout
awk perl stderr

답변4

입력 리디렉션을 설정하도록 쉘에 지시하려면 또는를 stderr사용 하고 파일 설명자 번호 앞에 다음을 붙일 수 있습니다.<<<<<<

./myprog 2< somefile.txt

또는

./myprog 2<<< "some text"

하지만 stderr그렇게 리디렉션하면 프로그램이산출즉, 프로그램(또는 프로그램이 사용하는 라이브러리)이 인쇄하려고 시도할 수 있는 오류 메시지가 표시되지 않으며, 추가로 프로그램이 해당 메시지를 작성하려고 하면 오류가 발생한다는 의미입니다.

현재 수행 중인 작업을 수행할 수 있는 다른 방법이 있는지 재고해 볼 수도 있습니다. 최소한 프로그램에 일부 입력을 제공하려는 아이디어라면 예를 들어 fd 3을 사용하는 것을 고려하십시오.

관련 정보