有時我不小心cat
得到一些二進位資料;有時一些 ncurses 程式崩潰 - 由於多種原因,終端可能會處於不良狀態,需要手動reset
。這種情況經常發生。
這種糟糕的狀態可能是無迴聲,或是將所有內容變成中文垃圾,或是許多其他東西。
有沒有什麼簡單的方法可以確保當 shell 重新獲得控制權時恢復終端(無需硬重置、清屏等)設定?
是的bash
,Terminal.app
但我猜這個問題幾乎是普遍存在的。
答案1
你提到的問題出現在不同的層面,只有其中一些問題可以透過「轉義碼」來解決。
終端仿真中的備用字元集
有一個常見的終端問題,可能被描述為“(某些)小寫字母顯示為符號或畫線字元”(請參閱這另一個問題)。這可能與你的“中國垃圾”問題無關,但這是我見過的最接近的事情。當將幾乎任何 8 位元資料流解釋為 UTF-16 編碼文字時,您也可能會遇到「中文垃圾」。通常這不是一個需要重置的“棘手”問題,因此這可能不是您所看到的問題。
「卡住畫線字元」問題通常來自於向終端模擬器發送無意的控制序列(或在切換到備用字元集後重置終端之前停止程式)。當顯示某些二進位資料且位元組流包含選擇備用字元集的終端控制序列時,可能會發生這種情況。
這在大多數 VT-100 型終端上很容易觸發,因為它只需要一個位元組(0x0e;請參閱我對之前連結的SO問題的回答)。重設此條件的控制序列也是單一位元組(0x0f;通常透過echo ^V^O
(鍵入為echo
Control+ V Control+O或直接鍵入為printf '\017'
)產生。
您可以透過讓提示包含 0x0f 位元組來解決此類問題** 。
** 如果您的「中國垃圾」是由於其他問題造成的,那麼它可能有不同的解決方案。
PS1="\[\017\]… "
和\[
在\]
那裡告訴巴什有界字符是非列印字符。這讓巴什準確了解「實體」遊標位置(這對於使用命令列編輯功能時正確重新顯示非常重要)。
正如伊格納西奧·巴斯克斯·艾布拉姆斯 (Ignacio Vazquez-Abrams) 在《他的回答,獲得所需控制序列的另一種方法是透過輸出命令:
tput rmacs
使用此方法,您可以避免修改 PS1,只需將上述命令放入 PROMPT_COMMAND 中:
PROMPT_COMMAND='tput rmacs'
TTY(termios)選項
「無迴聲」問題***來自基於作業系統的 tty 裝置選項的意外設置,該裝置將終端模擬器連接到終端視窗內運行的所有程式。這通常是由於互動式文字 UI 程式存在錯誤、崩潰或被終止而無法將 tty 恢復到原始狀態。
您可以使用以下命令控制這些設置史蒂命令。此類問題無法透過「轉義碼」解決,因為 tty 選項是透過軟體 API 配置的(請參閱tcsetattr(3)和術語(4))。一般來說stty sane
是一個很好的重置機制。
*** 還有「沒有 ^C/^Z/^/」、「階梯式輸出」(收到 LF 時沒有自動 CR)和其他幾個問題。
重置
這重置命令通常可以幫助解決這兩類問題。它將發送終端初始化控制序列,通常可以修復備用字元集問題,並將 tty 選項重設為合理的值。
問題在於重置是它還在某些系統上列印額外的訊息(例如“擦除是…”,“中斷是…”);您可能不希望在每次提示之前都顯示這些內容。如果您的實施重置將訊息和控制序列發送到不同的位置(例如,一個發送到 stdout,而另一個發送到 stderr),那麼您可能能夠過濾掉訊息(例如PROMPT_COMMAND='reset 2>/dev/null'
(見下文)並跳過將^O 放入提示中) 。
^O 和stty sane
在巴什,您可以將參數設定PROMPT_COMMAND
為命令和巴什將在顯示主提示之前運行。您可以將所有呼叫stty sane
放在那裡並在提示中放置 ^O :
PROMPT_COMMAND='stty sane'
PS1="\[\017\]… "
同樣,您可以透過使用避免修改 PS1(並處理非 VT-100 型終端)輸出(根據伊格納西奧·巴斯克斯·艾布拉姆斯的建議):
PROMPT_COMMAND='stty sane; tput rmacs'
答案2
放
echo -n "$(tput rmacs)"
在$PROMPT_COMMAND
。
答案3
所以我會少用命令列,在 xterm 或任何終端機中總是有一個「按鈕」重置或硬重置,對於terminal.app,它位於 Shell 選單下。發送硬重置 alt-command-r。