Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?
@yabeenico

tail -fをログ出力プロセスの終了と同時に終了

やりたいこと

次のシェルスクリプトにおいて、 longjob の終了と同時に tail -f を終了させたい。

#!/bin/bash

longjob &>log & disown
tail -f log

条件:

  • 1つのシェルスクリプト内で行いたい。
  • 端末が終了しても longjob は継続させたい (つまり、& disown は譲れない)。
  • Ctrl-c の押下時に tail は終了させたいが longjob は終了させたくない。

解決策1

tail -f の開始前に、以下を行うバックグラウンドプロセスをあらかじめ起動しておく。

  1. longjob が終了するまで待機。
  2. tail のプロセスを kill。
#!/bin/bash

longjob &>log & disown

(
    # set PID_JOB
    PID_JOB=$!

    # set PID_TAIL
    while test -z $PID_TAIL; do PID_TAIL=$(ps --ppid=$$ | grep tail | awk '$0=$1'); done

    # wait PID_JOB
    while ps -p $PID_JOB >/dev/null; do sleep 0.5; done

    # kill PID_TAIL
    kill -INT $PID_TAIL
) &

tail -f log
  • tail の開始前に PID_TAIL=$(...) の部分が実行された場合、 $PID_TAIL は空文字になる。PID_TAIL を確実に設定するために、 # set PID_TAIL の部分は while で回している。
  • 問題点: longjob が終了すると kill -INT が発砲され、tail が異常終了する。

解決策2

tail をバックグラウンドで一旦起動しおいて fg で処理を戻す。

#!/bin/bash -i

longjob &>log & disown
PID_JOB=$!

tail -f log &
PID_TAIL=$!

(
    # wait PID_JOB
    while ps -p $PID_JOB >/dev/null; do sleep 0.5; done

    # kill PID_TAIL
    kill -INT $PID_TAIL 2>/dev/null
) &

fg 1 >/dev/null

  • 注意: シェバングが #!/bin/bash -i
    • fg はインタラクティブシェルにおいて利用可。
    • インタラクティブシェルとしてシェルスクリプトを起動するため。
  • longjob 終了前に Ctrl-c した場合に kill が失敗するため、エラーを捨てる。
  • fg したときに tail -f log と表示されるのを防ぐため、標準出力を捨てる。

うまく行かない方法

tee & trap

# Ctrl-c で longjob が終了してしまう
longjob 2>&1 | tee log
# Ctrl-c で終了できない
trap '' 1 2 15
nohup longjob 2>&1 </dev/null | tee log
# longjob は最後まで実行されるが、Ctrl-c で teeが終了し、それ以降のログが記録されない
# longjob に "trap '' 1 2 15" を記述した上で
nohup longjob 2>&1 </dev/null | tee log

longjob に trap '' 1 2 15tee log を記述した上で解決策2のようなコードを書けばできるが美しくはない。

wait

# wait PID_JOB の部分を wait $PID_JOB とするとこうなる。

wait: pid 5734 is not a child of this shell
0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
0
Help us understand the problem. What is going on with this article?