Lessを使用してテキストプロパティをリセットする必要がないのはなぜですか?

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}
'

(스크립트에서) 세 번째 줄 끝에서 재설정하지 않으면 다음에 입력하는 명령(셸에서)을 포함하여 다음의 모든 줄에 밑줄이 그어집니다. 내가 도망칠 때까지 reset. less( )를 사용하는 것은 (스크립트에서) 불필요할 ./my-script.sh | less -R뿐만 아니라 (세 번째 줄에 밑줄이 그어져 있음) ( , )에 추가 기호가 생성됩니다 .resettmux^OTERM=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インターフェースが使用されるため削除されます^Olessタンキャップ機能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)を実装しているためできるケースをハードコードします。

関連情報