為什麼我不需要用less來重置文本屬性?
該腳本輸出 5 行,第三行加下劃線:
#!/usr/bin/env bash set -eu bold=$(tput bold) reset=$(tput sgr0) underline=$(tput smul) echo 'line 1 line 2 line 3 line 4 line 5' | awk -v bold="$bold" -v reset="$reset" -v underline="$underline" ' NR == 3 {print underline $0 reset} NR != 3 {print $0} '
如果我沒有在第三行的末尾重置(在腳本中),那麼以下所有行都帶有下劃線,包括我接下來鍵入的命令(在 shell 中)。直到我跑
reset
。使用less
(./my-script.sh | less -R
) 不僅reset
(在腳本中)不需要(第三行加下劃線),而且它還在tmux
(^O
,TERM=screen-256color
) 中產生額外的符號:line 1 line 2 line 3^O line 4 line 5
但在普通控制台 (
TERM=xterm-256color
) 中沒有符號。究竟是什麼以及為什麼會發生這種情況?有沒有辦法讓腳本在所有這些情況下都能正常工作?
$ ./my-script.sh $ ./my-script.sh | grep line --color=never $ ./my-script.sh | less -R
例如,使以下腳本更好地工作。
less
在行尾發送它自己的“重置”,這恰好是sgr0
通過(ncurses)消除^O
(重置備用字元集)從terminfo派生的,因為less
使用的是termcap介面。如手冊頁curs_termcap(3x)中所述,與 terminfo sgr0相對應的 termcap 功能me通常不會修改備用字元集狀態:請注意,termcap 與 terminfo 的**
sgr
字元串沒有任何相似之處。這樣做的一個後果是 termcap 應用程序假定me
**(terminfosgr0
) 不會重置備用字元集。此實現檢查並修改顯示到 termcap 介面的數據,以適應 termcap 在這方面的限制。也許
less
正在執行該重置以從意外的轉義序列中恢復:該-R
選項僅設計用於處理 ANSI 顏色(以及類似格式的轉義,例如粗體、下劃線、閃爍、突出)。原始碼沒有提到這一點,但A_NORMAL
分配告訴less
稍後發出重置:/* * Add a newline if necessary, * and append a '\0' to the end of the line. * We output a newline if we're not at the right edge of the screen, * or if the terminal doesn't auto wrap, * or if this is really the end of the line AND the terminal ignores * a newline at the right edge. * (In the last case we don't want to output a newline if the terminal * doesn't ignore it since that would produce an extra blank line. * But we do want to output a newline if the terminal ignores it in case * the next line is blank. In that case the single newline output for * that blank line would be ignored!) */ if (column < sc_width || !auto_wrap || (endline && ignaw) || ctldisp == OPT_ON) { linebuf[curr] = '\n'; attr[curr] = AT_NORMAL; curr++; }
作為替代方案**
sgr0
(它會重置所有**影片屬性,並且只被更少的部分理解),您可以這樣做reset=$(tput rmul)
和(對於許多終端/許多系統,包括
TERM=screen-256color
)僅重置下劃線。但是,這不會影響粗體,也沒有傳統的 terminfo/termcap 功能來重置粗體。但是 screen 實現了執行此操作的相應 ECMA-48 序列(SGR 22 與 中使用的 24rmul
),因此您可以對這種情況進行硬編碼。