web-dev-qa-db-ja.com

「less」は、ユーザーからコマンドを読み取ることができる一方で、標準入力からデータをどのように取得しますか?

ほとんどの人が何度も行っているように、lessを使用して長いテキストを表示すると便利です。

some_command | less

これで、そのstdinはパイプ(FIFO)に接続されました。どうすればup/down/quitなどのコマンドを読み取ることができますか?

47
iBug

William Pursell で述べたように、lessはターミナルからユーザーのキーストロークを読み取ります。制御端末である/dev/ttyを明示的に開きます。これにより、標準入力とは別のファイル記述子が提供され、そこからユーザーのインタラクティブ入力を読み取ることができます。必要に応じて、標準入力から表示するデータを同時に読み取ることができます。 (必要に応じて、端末に直接writeすることもできます。)

あなたはこれを実行して見ることができます

some_command | strace -o less.trace -e open,read,write less

入力を移動してlessを終了し、less.traceの内容を確認します。/dev/ttyが開いていることがわかり、ファイル記述子0と、返されたファイル記述子0の両方から読み取られます。 /dev/ttyを開きました(おそらく3)。

これは、端末からの読み取りと端末への書き込みを確実に行いたいプログラムの一般的な方法です。 1つの例は、SSHですたとえばパスワードまたはパスフレーズを要求されたとき。

説明schily によって、/dev/ttyを開けない場合、lessは標準エラー(ファイル記述子2)から読み取ります。 lessによる/dev/ttyの使用は、1991年4月2日にリリースされたバージョン177で導入されました。

Suggested by Hagen von Eitzen としてcat /dev/tty | lessを実行しようとすると、less/dev/ttyを開くことに成功しますが、失敗しますcatが入力を閉じるまで、入力を取得します。したがって、画面が空白になり、押すまで何も表示されません。 CtrlC catを殺す(または他の方法で殺す)。次に、lessは、catの実行中に入力したものをすべて表示し、それを制御できるようにします。

52
Stephen Kitt

UNIXは、stdinがリダイレクトされている間にユーザー入力を読み取るための2つの方法を提供します。

  • 元の方法はstderrから読み取ることです。 Stderrは書き込み用に開いていますand読み取り、これはまだPOSIXで言及されています。

  • 以降のUNIXバージョンでは(1979年頃)、プロセスの制御ttyを開くことができる/dev/ttyドライバインターフェイスが追加されました。制御ttyのないプロセスがあるため、/dev/ttyを開こうとすると失敗する可能性があります。したがって、フレンドリーなソフトウェアは元の方法にフォールバックし、stderrから読み取ろうとします。

27
schily