less(1) でテキスト検索を終了し、Unix パイプで読み続ける

less(1) でテキスト検索を終了し、Unix パイプで読み続ける
gunzip < 100terabytes.txt.gz | less

less(1)画面を埋めるのに必要な数の行を読み、停止しますread(2)。その結果、配管がいっぱいになるとgunzip(1)詰まります。write(2)

下にスクロールすると、less(1)質問が引き続きエクスポートされ、read(2)パイプが消費されるとgunzip(1)許可されますwrite(2)。ここで前後に移動できる完全な柔軟性があります(gunzip < 100terabytes.txt.gzまだ完了していないと仮定)。

今まではそんなに良くなった。

less(1)テキスト検索の開始を使用できます/。ただし、検索文字列が で見つからないと、100terabytes.txtデフォルトless(1)では応答しなくなります。検索出口を使用できますCtrl-Cしかし、gunzip(1)との間のパイプを閉じたようですless(1)。私はこれが嫌いです。gunzip(1)テキスト検索を放棄したら、手動で下にスクロールしてより多くの行を使用したいと思います。可能ですか?

はいいいえアドバイスを求めてください。gunzip < 100terabytes.txt.gz | grep pattern | less

修正する

試してみることができますod -v /dev/zero | less

ベストアンサー1

を押すとCtrl+Cフルシェルになります。働く(プロセスグループ)SIGINTを受け取り、lessそれを傍受して検索を中断しますがgunzip終了します。これを防ぐには、次のようにします。

(trap '' INT; gunzip < file.gz) | less

これはSIGINTを無視しますが、gunzipそれ以降は中断できません。gunzip

については大丈夫かもgunzipしれません。終了するだけでは、次回何かを書くときにSIGPIPEと一緒に死ぬからです。ただし、何かを出力せずに停止するアプリケーションの場合、これはより大きな質問になります(まだ可能です。SIGTSTPまたはSIGQUITを使用しているless場合)。gunzipCtrl+ZCtrl+\

また、独自のSIGINTハンドラをインストールpvまたはインストールするなどの一部のコマンドは。pingtrap '' INT

入力を保存する関数を作成できます。たとえば、次のようになります。

iless() {
  (trap '' INT; "$@") | less
}

iless gunzip < file.gz

または:

noint() (trap '' INT; "$@")

noint gunzip < file.gz | less

ただし、次の点に注意してください。

gunzip < file.gz | grep foo | less

あなたはそれを書く必要があります:

noint gunzip < file.gz | notint grep foo | less

または:

noint eval 'gunzip < file.gz | grep foo' | less

または:

iless eval 'gunzip < file.gz | grep foo'

別の方法は、プロセス置換を使用することです。

less -f <(gunzip < file.gz | grep foo)

または(にはありませんがzsh):

less < <(gunzip < file.gz | grep foo)

この場合、シェルにはフォアグラウンドプロセスグループのプロセス置換コマンドは含まれません(forの2番目の場合を除くzsh)。そのプロセスグループはシェルのプロセスグループと同じです。これは、を押すとSIGINTを受信しないことを意味しますCtrl+C

これらのプロセスは、Ctrl+Zまたはの影響を受けませんCtrl+\

zsh、およびでksh93テストされましたbash

おすすめ記事