Bash

將 stderr 全域重定向到 /dev/null 後的不可見提示

  • August 26, 2018

學習TLDP 的 Advanced Bash-Scripting Guide我無法從 tty 和 pts 在 debian 9 的 bash 4.4.12 中重建以下 shell 輸出:

bash$ lsof -a -p $$ -d0,1,2
COMMAND PID     USER   FD   TYPE DEVICE SIZE NODE NAME
bash    363 bozo        0u   CHR  136,1         3 /dev/pts/1
bash    363 bozo        1u   CHR  136,1         3 /dev/pts/1
bash    363 bozo        2u   CHR  136,1         3 /dev/pts/1


bash$ exec 2> /dev/null
bash$ lsof -a -p $$ -d0,1,2
COMMAND PID     USER   FD   TYPE DEVICE SIZE NODE NAME
bash    371 bozo        0u   CHR  136,1         3 /dev/pts/1
bash    371 bozo        1u   CHR  136,1         3 /dev/pts/1
bash    371 bozo        2w   CHR    1,3       120 /dev/null

每當我執行第二個命令時,shell 提示符就會消失,並且所有鍵盤輸入都停止顯示,儘管我仍然可以執行命令並查看它們的輸出。這是為什麼?

這是因為您重定向了 shell 的標準錯誤。

根據標準,這就是符合 POSIX 的 shell 應該編寫其互動式提示的地方。

然而,不回顯輸入行為要復雜得多:

  • Debian PD Korn、Debian Almquist 和 Heirloom Bourne shell 沒有實現它們自己的行編輯器,而是依賴於核心中終端行規則提供的編輯器。您仍然會看到回顯您鍵入的內容作為他們的標準輸入。
  • Watanabe、(FreeBSD 93) Korn 和 (Debian 93) Korn shell 實現了它們自己的行編輯器,當它們(重新)顯示正在編輯的輸入行時,它們也會寫入標準錯誤。但是,他們在執行命令之前打開了終端回exec並且(因為標準錯誤不再是終端設備)在為他們的下一個輸入呼叫行編輯器時*無法再次關閉它。*因此,即使來自 shell 行編輯器的輸入回顯將轉到現在重定向的標準錯誤,您也會看到您鍵入的更多輸入由終端行規則回顯。他們的行編輯器也會以微妙的方式出錯,例如無法辨識任何進一步的終端尺寸變化。
  • MirBSD Korn、(FreeBSD PD) Korn 和 (OpenBSD PD) Korn shell 實現了它們自己的行編輯器,它們(重新)將已編輯的行顯示為標準錯誤,但直接打開另一個文件描述符/dev/tty以控制終端回顯等內容. 在為下一個輸入呼叫行編輯器時,他們成功地再次關閉了迴聲。因此,您將不會看到您鍵入的進一步輸入由他們的行編輯器終端行規則回顯。
  • Bourne Again 和 FreeBSD Almquist shell 實現了它們自己的行編輯器,它們(重新)將已編輯的行顯示為標準錯誤,但使用標準輸入來控制諸如終端回顯之類的東西。在為下一個輸入呼叫行編輯器時,他們成功地再次關閉了迴聲。因此,您將不會看到您鍵入的進一步輸入由他們的行編輯器終端行規則回顯。
  • BusyBox AlmquistZ shell 在這方面不符合 POSIX。他們都實現了自己的行編輯器。通過這兩種方法,您將看到該附錄使您相信會發生的行為。

    • BusyBox Almquist shell 的行編輯器使用標準輸出作為輸入回顯,這也是它編寫提示的地方。它根本不受標準錯誤重定向的影響。但是您可以通過重定向標準輸出來獲得效果。它使用標準輸入來辨識終端尺寸的變化。
    • Z shell 努力嘗試找到一個終端設備來執行 ZLE,直到並包括顯式打開/dev/tty. 它在啟動時將文件描述符複製到終端設備,然後 ZLE 將其用於所有內容;用於回顯鍵入的輸入、讀取鍵入的輸入、寫入互動式提示以及打開和關閉終端回顯。因此,ZLE 不受標準錯誤、輸出甚至輸入的後續重定向的影響。如果您願意,您可以將所有三個重定向到/dev/nullexecZ shell 仍會以互動方式提示您並接收輸入。

Thompson shell 首先不支持 shellexec命令機制,因為它早於它的發明。)

你應該向作者 Stéphane Chazelas 抱怨那個附錄是錯誤的,這樣它可能會得到修復。

進一步閱讀

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