以下file1 file2 | 猫—なぜ機能するのですか?


21

I USSときless file1 file2、私は「少ないバッファビューア」に示されている両方のファイルを取得しますが、less file1 file2 | catstdoutに付加し、両方のファイルの内容を印刷します。「less buffer viewer」を表示するか、次のコマンドの出力をstdoutに生成する必要があるかどうかは、どのようにしてわかりませんか?これを行うためにどのメカニズムが使用されますか?

回答:


30

lessテキストを標準出力に出力します。標準出力

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

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

bashではtestを使用できます(を参照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'

1
@tfh STDOUTがパイプまたはリダイレクトに接続されていない場合、STDOUTがパイプまたはリダイレクトに接続されていることを出力しないのは正しいことです。3つすべてをスクリプトに入れます。コールはbash script.shbash script.sh | catbash script.sh > file、とあなたは何を得るの出力を参照します。
hvd 16

1
stdout「ファイルに書き込む」ことができるものではありません。それはあなたがwrite() するものです。 less出力がファイル、パイプ、ソケット、ブロックデバイスなどのいずれであるかに応じて、異なる処理を行う必要はありません。ttyではないことが重要であるため、のように動作しcatます。(あなたはこれを知っていて、それを説明するのに間違った言葉を選んだと思いますが、他の読者のためにこれを指摘したいと思いました)。
ピーターコーデス

ですから、私の特定の質問で猫のように振る舞うのはより少ないタスクです-より一般的には、パイプラインの次のコマンドのように振る舞います。私が理解したことから、まったく同じ動作が別のツールにも実装されているとは想定できません。
tfh 16

@tfh:いいえ、次のless「図」にはなりませんcatcatstdoutがttyではない場合、次の内容に関係なく動作します。
ピーターコーデス

@MichaelD .:ありがとう、私の答えを修正しました。それlessが先に進み、1つのTCGETSを使用して端末の寸法を取得するか、それがttyではないことを発見すると思いましたが、どうやら間違っていると思いました。
ピーターコーデス

6

lessstdout端末であるかどうかを確認し、端末でcatない場合と同様に動作します(EOFまでstdinをstdoutにコピーします)。

この機能を使用すると、ファイルへの簡単なリダイレクトを許可--helplessながら、常に出力(例:出力)を送信するスクリプトまたはプログラムを作成できます。some_command --fullhelp > help.txtstdinのスペースバーがテキストまたは何かをページングするのをまだ待っているなら、それはうんざりするでしょう。一部のコマンド(例man:)は、自分の出力をチェックして、ページャー経由で出力を送信するかどうかを決定します。あなたが走るならman ls > ls.txt、それはあなたの$PAGER

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


less端末の寸法を把握する必要があります(画面サイズ、一度に表示する行数を知るため)。ioctl(2)それは上の使用していますstdout、それはとにかく非端子ケースを扱う避けることができないので、非端末にENOTTYが返されます。 less実際にはisatty(3)端末の寸法をチェックする前に使用しますがisatty、ttyのみのioctlを試し、エラーがないかどうかをチェックすることで機能します。

more(1)(少なくともutil-linuxバージョンのような)単純なページャーでさえ、この機能を備えています。これはおそらく、その場合に実装する最も単純な正気の振る舞いだからです。


あなたはパイプに何かすることを注意 less(例えばgrep foo bar.txt | less)、それを開く必要がない/dev/ttyキーボード入力のために。(これを行うには、を参照してくださいecho foo | strace less)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.