問題
例えば、
./script.sh | less
の際に、script.sh
内からless
のPIDを取得したい時。
取得する
pipe=$(readlink /proc/$$/fd/1 | sed -e 's/pipe:\[\([0-9]*\)\]/\1/g')
pid=$(lsof -n -P -u $USER 2> /dev/null | awk "{if (\$4 ~ 0r && \$8 ~ $pipe) print \$2}")
流れ
/proc/$$/fd/1
は、標準出力(すなわちパイプ)のファイルデスクリプタで、これの実体はpipe:[XXXXXX]
みたいなファイル(パイプ)。
これの名前をreadlink
で読んで、sed
でXXXXXX
の部分を取り出しています。($pipe
)
さて、lsof
で開かれているファイル(パイプ含む)の一覧が出てくるので、エラーを捨てつつ先程のパイプ番号を含む行の出力側のPIDをゲット。($pid
)
lsof
は遅いので、ユーザーを-u
で絞ることで高速化を図りました
注意
出力がパイプされている前提なので、もし実際に使う場合は確認を挟んだほうがいいと思いました
if [ -t 1 ]; then
echo "Not piped..."
else
echo "Piped..."
fi
下記環境で検証していますが他の環境(macとか)だと動かないかもしれません
- linux 4.15.7-1-ARCH
- bash 4.4.19
- lsof 4.90