Max*_*kyi 5 bash file-descriptors stdout
例如,当我在Bash 中执行程序时[ls][2],它会将其输出发送到标准输出( fd &1)。并且执行程序的输出显示在终端中。Bash/终端如何获取ls命令的输出?
作为 shell 的子进程,ls继承了 shell的打开文件描述符。并且标准文件描述符(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
Run Code Online (Sandbox Code Playgroud)
也就是说, 的输出ls,或者 shell 本身,不是由 shell 处理的,而是由终端模拟器(GNOME 终端、终结器、xterm 等)处理的。
你可以测试一下:
在 Linux 上,找到pts您的终端模拟器(例如 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
Run Code Online (Sandbox Code Playgroud)
现在,非标准 fds(除 0,1,2 之外的那些)gnome-terminal将被它用来为 shell 提供输入和输出。终端仿真器读取发送到该 PTS 的数据,并(经过一些处理,用于颜色等)将其显示在屏幕上。在这种情况下,这将是15,连接到pts/20。如果我向那个 pts 写一些东西,我可以期望它出现在那个终端中:

进一步阅读:
另一种情况,我做这样的事情:
echo $(ls)
a=$(date)
vim `command -v some_script`
Run Code Online (Sandbox Code Playgroud)
称为命令替换。在命令替换中,命令的输出由 shell 本身捕获,并且永远不会到达终端,除非您确实将其打印出来(例如,echo $(ls))。此案例在Hauke Laging 的回答中处理。