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