스크립트는 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}
'
(스크립트에서) 세 번째 줄 끝에서 재설정하지 않으면 다음에 입력하는 명령(셸에서)을 포함하여 다음의 모든 줄에 밑줄이 그어집니다. 내가 도망칠 때까지 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
예를 들어, 만들기 위해서는다음 스크립트더 잘 일하십시오.
答え1
less
行末に独自の「リセット」を送信します。これはsgr0
(ncurses)を介してterminfoから派生し、termcapインターフェースが使用されるため削除されます^O
。less
タンキャップ機能私terminfoに対応sgr0代替文字セットの状態は通常、マニュアルページに記載されているように変更されません。curs_termcap(3x):
termcapにはterminfoに似たものはありません。
sgr
ひも。これの1つの結果は、termcapアプリケーションが次のことを前提としていることです。me
(用語情報sgr0
) は代替文字セットをリセットしません。この実装では、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
(これによりリセットされます。みんなvideoプロパティであり、lessで部分的にのみ理解されます)、次のことができます。
reset=$(tput rmul)
そして(多くの端末/多くのシステムを含むTERM=screen-256color
)下線のみがリセットされます。しかし、これは影響を与えません。勇敢な、そして太字をリセットする従来のterminfo / termcap機能はありません。ただし、画面は対応するECMA-48シーケンス(SGR 22と24で使用rmul
)を実装しているためできるケースをハードコードします。