파일 설명자 리디렉션 사용 - 구체적인 예

파일 설명자 리디렉션 사용 - 구체적인 예

내가 읽고 있어요이 문서리디렉션 및 파일 설명자와 관련된 다음 예가 제공됩니다.

ls > dirlist 2>&1

표준 출력과 표준 오류를 파일의 디렉토리 목록으로 보내는 반면, 명령은

ls 2>&1 > dirlist

표준 출력만 dirlist로 지정됩니다. 이는 프로그래머에게 유용한 옵션입니다.

이러한 예가 잘못된 것인가요? 내 생각에는두번째예를 들어 "표준 출력 및 표준 오류를 파일의 디렉터리 목록에 직접 지정"하는 반면첫 번째예를 들어 "디렉토리 목록에만 표준 출력을 보냅니다."

내가 틀렸다면(...아마도...) 누군가 이 두 예의 논리를 명확하게 설명할 수 있습니까?

답변1

n>&m먼저 구문을 알아야 합니다 . 이는 복사 작업입니다. 즉, m이 n으로 복사됩니다. 섹션 보기"3.6.8 파일 설명자 복사".

이 글을 읽으면서 저와 같은 질문이 생겼습니다. 그래서 나는 당신에게 그것을 설명하려고 노력할 수 있습니다:

ls > dirlist 2>&1 

위 명령을 사용하여 먼저 출력을 dirlist로 리디렉션합니다 > dirlist. 2>&1파일 설명자 1을 2로 복사하는 것, 즉 fd2를 fd1의 복사본으로 만드는 것을 나타냅니다. 이제 fd1이 이미 dirlist를 가리키고 있으므로 fd2를 fd1의 복사본으로 만드는 것은 fd2도 dirlist를 가리킨다는 것을 의미합니다. 결과는 fd1->dirlist, fd2->dirlist입니다.

ls 2>&1 > dirlist   

이런 방식으로 먼저 fd2를 fd1의 복사본으로 만듭니다. fd1은 여전히 ​​터미널이므로 fd2->터미널입니다. 그런 다음 fd1을 디렉터리 목록으로 리디렉션합니다. 결과는 fd2 -> 터미널, fd1->dirlist입니다.

답변2

방향은 왼쪽에서 오른쪽으로 처리됩니다.

ls > dirlist 2>&1

쉘이 결국 다음 시스템 호출을 실행하여 ls로 바뀌도록 합니다(간결함을 위해 오류 검사는 생략됨).

/* Handle > dirlist */
int temp_fd = open("dirlist",O_WR);  /* Open dirlist for output */
dup2(temp_fd, 1); /* Make file descriptor 1 (stdout) point to dirlist */
close(temp_fd);  /* Don't need this other file descriptor for dirlist */
/* Handle 2>&1 */
dup2(1,2); /* Make fd 2 be a copy of fd 1, which points to dirlist */

따라서 먼저 fd 1을 변경한 다음 fd 2를 변경합니다.

대신 ls 2>&1 > dirlist는

/* Handle 2>&1 */
dup2(1,2); /* Make fd 2 be a copy of fd 1, the original stdout */
/* Handle > dirlist */
int temp_fd = open("dirlist",O_WR);  /* Open dirlist for output */
dup2(temp_fd, 1); /* Make file descriptor 1 (stdout) point to dirlist */
close(temp_fd);  /* Don't need this other file descriptor for dirlist */

그것을 보는 또 다른 방법은 숙제로 보는 것입니다. 원래 fd1=initial_stdout이면

/* ls > dirlist 2>&1 */
fd1=to_dirlist
fd2=fd1 (i.e. to_dirlist)

/* ls 2>&1 > dirlist */
fd2=fd1 (i.e. initial_stdout)
fd1=to_dirlist.

copy by value아니면 대신 이라고 말할 수도 있습니다 copy by reference.

관련 정보