__sil
@__sil

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

lessでFコマンドを使うと、バックグラウンドで走らせていたtailがなぜか終了する

タイトルの通りなのですが、Bashスクリプト内でlessコマンドを呼び出しファイルへの追記を監視すると、全く無関係にバックグラウンド実行していたtailコマンドが終了してしまいます。

#!/bin/bash
mytrap() {
  kill "$tailpid"
}
trap mytrap EXIT
tail -f ./tail.txt > >(cat > ./output.txt) &
tailpid=$!
less ~/.bashrc

現象が再現するできるだけ単純なシェルスクリプトを書いてみました。
内容はなんでもいいのでtail.txtという名前のファイルをカレントディレクトリに用意して、上のシェルスクリプトを実行してみてください。

lessコマンドによってBashの設定ファイルの内容が表示されると思います。
そのままqキーを押していただくと、lessコマンドが終了します。
lessコマンドの終了をもってシェルスクリプト自体も終了し、その際関数mytrapが呼び出されることでバックグラウンドで走っていたtail -fも終了します。

では次に、もう一度シェルスクリプトを実行してください。
またlessコマンドの画面が表示されますが、今度はShift+Fを押して追記監視モードに入ってください。
入ったらすぐにCtrl+Cで通常モードに戻って大丈夫です。
その後、qキーを押してlessコマンドを終了します。
するとtail -fを終了しようとしたkillコマンドが、「そのようなプロセスはありません」というエラーメッセージを吐きます

psコマンドを使って調べてみると、どうもCtrl+Cで追記監視モードから抜けたときになぜかtail -fが終了しているようです。

さらに奇妙なことに、tailコマンドの出力先がプロセス置換ではない通常のファイルであればこの現象は起こりません
つまり、tail -fのところの行を

tail -f ./tail.txt > ./output.txt &

とすると、tail -fはkillされるまで生存します。

一応tailやlessのマニュアルは読んでみたのですが、なぜこのような現象が起こるのかわかりませんでした。
この挙動のせいで困っているわけではありませんが、どうしてこんなことになるのか気になります。
何が起こっているかわかる方がいらっしゃたらこの現象の解説をいただきたいです。

0

1Answer

入ったらすぐにCtrl+Cで通常モードに戻って大丈夫です。

Ctrl+Cでシェルスクリプトが終了してしまうのではありませんか?

trap "" 2

を入れてみるとどうでしょう?

1Like

Comments

  1. @__sil

    Questioner

    たしかに

    trap "" 2
    

    を入れるとtailを正常にkillできるようになりました。
    これは、Ctrl+Cによってプロセス置換内のcatにSIGINTが届いてしまっているのでtailも終了するということですか?

  2. 多分そういうことなんじゃないでしょうか
    less を tailモードにしなくても Ctrl+C だけで同様の挙動になりますね。
    大元のスクリプトも、そこから呼ばれたサブシェルもみんな SIGINT を受け取っちゃうんじゃないでしょうか。

Your answer might help someone💌