web-dev-qa-db-ja.com

少ないfile1 file2 |猫-それはなぜ機能するのですか?

私が使うときless file1 file2 "less buffer viewer"に両方のファイルが表示されますが、less file1 file2 | catは、stdoutに追加された両方のファイルの内容を出力します。次のコマンドのために、「less buffer viewer」を表示する必要があるのか​​、それともstdoutに出力を生成する必要があるのか​​、あまり知らないのですか?これにはどのようなメカニズムが使用されますか?

21
tfh

lessはテキストを標準出力に出力します。 stdoutが行く

  • terminal(/ dev/tty?)に移動し、デフォルトのバッファビューアを開きます
  • |を使用して別のプログラムにパイプするとき、pipeを介して(less text | cut -d: -f1
  • >fileにリダイレクトする場合、>(less text > tmp

"isatty"と呼ばれるC関数があり、出力がttyに送られるかどうかをチェックします(4.81未満、main.c、112行目)。その場合は、バッファビューアを使用します。それ以外の場合は、catのように動作します。

Bashでは、テストを使用できます(man test

  • -t FDファイル記述子FDが端末で開かれている
  • -p FILEが存在し、名前付きパイプです

例:

[[ -t 1 ]] && \
    echo 'STDOUT is attached to TTY'

[[ -p /dev/stdout ]] && \
    echo 'STDOUT is attached to a pipe'

[[ ! -t 1 && ! -p /dev/stdout ]] && \
    echo 'STDOUT is attached to a redirection'
30
Michael D.

lessは、そのstdoutがターミナルであるかどうかをチェックし、ターミナルでない場合はcatのように動作します(EOFまでstdinをstdoutにコピーします)。

この機能を使用すると、lessを介して常に出力(_--help_出力など)を送信するスクリプトまたはプログラムを記述しながら、ファイルに簡単にリダイレクトできます。 _some_command --fullhelp > help.txt_がまだstdinのスペースバーでテキストなどをページングするのを待っていると、それはうまくいきません。一部のコマンド(例:man)は、自身の出力をチェックして、ポケットベルを介して出力を送信するかどうかを決定します。 _man ls > ls.txt_を実行すると、_$PAGER_が呼び出されることはありません。

lessの猫のような動作は、パイプラインにステージを追加するときに、ワンライナーから編集するのを忘れた場合にも便利です。


lessは、端末の寸法(一度に表示する行数を知るための画面サイズ)を把握する必要があります。 ioctl(2)stdoutで使用すると、非端末でENOTTYが返されるため、非端末のケースの処理を回避することはできません。 lessは実際には isatty(3) を使用してから端末の寸法を確認しますが、isattyはttyのみのioctlを試行してエラーがないか確認することで機能します。

more(1)のような単純なポケットベル(少なくともutil-linuxバージョン)にもこの機能があります。これは、その場合に実装するのがおそらく最も簡単で正気な振る舞いだからです。


パイプintoless(例_grep foo bar.txt | less_)をパイプする場合、_/dev/tty_を開く必要があることに注意してください。キーボード入力用。 (これは_echo foo | strace less_で確認できます)。

6
Peter Cordes