Bash에서 실행된 프로그램의 출력을 얻는 방법은 무엇입니까?

Bash에서 실행된 프로그램의 출력을 얻는 방법은 무엇입니까?

프로그램을 실행할 때불다, 예를 들어 [ls][2]는 출력을 다음으로 보냅니다.표준 출력( fd &1). 그리고 실행된 프로그램의 출력이 터미널에 표시됩니다. Bash/terminal ls에서 명령의 출력을 얻는 방법은 무엇입니까?

답변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 등)에서 처리됩니다.


이것을 테스트할 수 있습니다:

ptsLinux에서는 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로 설정합니다. 따라서 자식 프로세스가 작성한 모든 내용은 stdoutfd 3의 부모 쉘에서 읽을 수 있습니다.

관련 정보