Bash
在程式碼“{ exec >/dev/null; } >/dev/null”中發生了什麼?
當您重定向包含 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"
一步步。
- 有兩個命令:
一種。
{ 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"
。標準輸出是它在第一個命令之前的任何位置。