답변1
쉘의 하위 프로세스로서 ls
쉘의 열린 파일 설명자를 상속받습니다. 표준 파일 설명자(stdin, stdout, stderr(또는 0, 1, 2))는 의사 터미널에 연결되고 터미널 에뮬레이터에 의해 처리됩니다.
예를 들어(Linux 시스템의 경우):
$ ls /proc/$$/fd -l
total 0
lrwx------ 1 muru muru 64 Dec 10 16:15 0 -> /dev/pts/3
lrwx------ 1 muru muru 64 Dec 10 16:15 1 -> /dev/pts/3
lrwx------ 1 muru muru 64 Dec 10 16:15 2 -> /dev/pts/3
lrwx------ 1 muru muru 64 Dec 10 16:15 255 -> /dev/pts/3
$ ls /proc/$(pgrep terminator -f)/fd -l | grep pts/3
lrwx------ 1 muru muru 64 Dec 10 16:15 26 -> /dev/pts/3
즉, 의 출력 ls
또는 셸 자체는 셸에서 처리되지 않고 터미널 에뮬레이터(GNOME 터미널, 터미네이터, xterm 등)에서 처리됩니다.
이것을 테스트할 수 있습니다:
pts
Linux에서는 GNOME 터미널과 같은 터미널 에뮬레이터에서 사용하는 의사 터미널( )을 찾으세요.
$ ls -l /proc/$(pgrep -n gnome-terminal)/fd | grep pts
lrwx------ 1 muru muru 64 Dec 10 18:00 1 -> /dev/pts/1
lrwx------ 1 muru muru 64 Dec 10 18:00 15 -> /dev/pts/20
lrwx------ 1 muru muru 64 Dec 10 18:00 2 -> /dev/pts/1
이제 비표준 fd(0, 1, 2 이외의 fd)를 사용하여 gnome-terminal
쉘에 입력 및 출력을 제공합니다. 터미널 에뮬레이터는 이 PTS로 전송된 데이터를 읽어서 화면에 표시합니다(색상 등 일부 처리). 이 경우에는 15
에 연결 합니다 pts/20
. 지금까지 뭔가를 쓰면 이 터미널에 나타날 것으로 예상할 수 있습니다.
추가 자료:
또 다른 경우에 내가 하는 일은 다음과 같습니다.
echo $(ls)
a=$(date)
vim `command -v some_script`
~라고 불리는명령 대체. 명령 대체에서 명령의 출력은 쉘 자체에 의해 캡처되며 인쇄하지 않는 한(예: echo $(ls)
) 터미널에 도달하지 않습니다. 사건은 다음에서 처리되었습니다.호크 라킨의 답변.
답변2
제가 질문을 명령 대체의 의미로 오해한 것으로 나타났습니다. 이 경우에만 쉘이 출력 처리에 참여합니다.
이것도 관심을 불러일으킬 수 있기를 바랍니다...
strace -p 2140
이 ll을 실행하기 전에 echo $(/bin/echo foo)
쉘에 연결합니다. 이는 결과의 일부입니다.
pipe([3, 4])
pipe([5, 6])
...
read(3, "foo\n", 128)
자식 프로세스에서는 다음과 같은 일이 발생합니다.
dup2(4, 1)
close(4)
close(3)
...
execve("/bin/echo", ...
셸은 파일 설명자 3과 4를 연결한 다음 분기합니다. 하위 프로세스는 stdout
새 프로그램을 실행하기 전에 fd를 4로 설정합니다. 따라서 자식 프로세스가 작성한 모든 내용은 stdout
fd 3의 부모 쉘에서 읽을 수 있습니다.