Bash

在程式碼“{ exec >/dev/null; } >/dev/null”中發生了什麼?

  • December 21, 2016

當您重定向包含 exec 重定向的命令列表時,exec >/dev/null 似乎在之後仍不會應用,例如:

{ exec >/dev/null; } >/dev/null; echo "Hi"

“嗨”被列印出來。

我的印{}像是命令列表不被視為子shell,除非它是管道的一部分,所以exec >/dev/null在我看來,它仍然應該應用在目前的shell環境中。

現在,如果您將其更改為:

{ exec >/dev/null; } 2>/dev/null; echo "Hi"

沒有預期的輸出;文件描述符 1 仍然指向 /dev/null 以供將來的命令使用。這通過重新執行來顯示:

{ exec >/dev/null; } >/dev/null; echo "Hi"

這不會給出任何輸出。

我嘗試製作一個腳本並跟踪它,但我仍然不確定這裡到底發生了什麼。

在這個腳本的每一點,STDOUT 文件描述符發生了什麼?

編輯:添加我的 strace 輸出:

read(255, "#!/usr/bin/env bash\n{ exec 1>/de"..., 65) = 65
open("/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fcntl(1, F_GETFD)                       = 0
fcntl(1, F_DUPFD, 10)                   = 10
fcntl(1, F_GETFD)                       = 0
fcntl(10, F_SETFD, FD_CLOEXEC)          = 0
dup2(3, 1)                              = 1
close(3)                                = 0
close(10)                               = 0
open("/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fcntl(1, F_GETFD)                       = 0
fcntl(1, F_DUPFD, 10)                   = 10
fcntl(1, F_GETFD)                       = 0
fcntl(10, F_SETFD, FD_CLOEXEC)          = 0
dup2(3, 1)                              = 1
close(3)                                = 0
dup2(10, 1)                             = 1
fcntl(10, F_GETFD)                      = 0x1 (flags FD_CLOEXEC)
close(10)                               = 0
fstat(1, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
ioctl(1, TCGETS, 0x7ffee027ef90)        = -1 ENOTTY (Inappropriate ioctl for device)
write(1, "hi\n", 3)                     = 3

讓我們跟隨

{ exec >/dev/null; } >/dev/null; echo "Hi"

一步步。

  1. 有兩個命令:

一種。{ exec >/dev/null; } >/dev/null, 其次是

灣。echo "Hi"

shell首先執行命令(a),然後執行命令(b)。 2. 收益執行{ exec >/dev/null; } >/dev/null如下:

一種。首先,shell 執行重定向>/dev/null 並記住在命令結束時撤消它

灣。然後,shell 執行{ exec >/dev/null; }.

C。最後,shell 將標準輸出切換回原處。(這與中的機制相同ls -lR /usr/share/fonts >~/FontList.txt——重定向僅在它們所屬的命令的持續時間內進行。) 3. 一旦第一個命令完成,shell 就會執行echo "Hi"。標準輸出是它在第一個命令之前的任何位置。

引用自:https://unix.stackexchange.com/questions/331764