Quantcast
Channel: Bashタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 2873

パイプで繋がったコマンドをバックグラウンドで実行した際に、最初のプロセスのプロセスIDを取得する

$
0
0
シェルにおいて、バックグラウンド実行のプロセスIDは$!で取得することができる。 sleep 10 & echo $! # sleepコマンドのプロセスIDが取得できる。 では、コマンドがパイプで繋がれている場合はどうなるだろうか? tail -f log.txt | grep 'keyword' & echo $! この場合、$!で取得されるのは、パイプの後半のプロセスgrepコマンドのプロセスになる。 ここで問題となるのはkill $!として、grepをキルしてもtailのプロセスが残ってしまうことである。 $ kill $! # grepのみがキルされる $ ps aux | grep tail # tailのプロセスがまだ残っている # > 9210 0.0 0.0 34122900 900 s000 SN 6:17PM 0:00.00 tail -f log.txt 前半のプロセスのプロセスIDを取得するにはどうすれば良いだろうか? 答えを言うと以下のようにすればよい。 tail -f log.txt > >(grep 'keyword') & echo $! # $!はtailのプロセスIDになっている ここで見慣れない文法 >( コマンド ) というものがある。 これはコマンド置換と呼ばれるbashの文法で、コマンドを実行したときのIOをファイルのように扱うことができるものである。 (参考:https://techblog.raccoon.ne.jp/archives/53726690.html ) つまり、tail -f ...の結果をリダイレクトした先は本来ならファイルであるはずだが、そのファイルへの書き出しがgrep ...の標準入力に渡されるようになる。 一般にプロセス置換を使うと cmd1 | cmd2 とパイプで繋ぐものと等価なものがcmd1 > >(cmd2)として実現できる。 しかし、パイプと違うのがバックグラウンド実行した際に$!で得られるプロセスID。コマンド置換を使った場合、前半のtailのコマンドのプロセスIDが取得される。 これによってkill $!としても、tailが残ってしまうことなく終了するし、ついでにgrepプロセスも終了する。 参考: https://stackoverflow.com/questions/1652680/how-to-get-the-pid-of-a-process-that-is-piped-to-another-process-in-bash

Viewing all articles
Browse latest Browse all 2873

Trending Articles