#!/bin/bash
mkfifo /var/run/out
while true
do
cat /var/run/out | nc -l 8080 > >(
while read line
do
do some stuff
done
)
done
nc
合計のpidをどのように取得できますかcat
? $!を使用すると機能しません。 pidファイルに書きたいです。
答え1
必要なものを実行するよりエレガントな方法があるかもしれませんが、次のように動作します。
do
(cat /var/run/out& echo $! > cat_pid; wait) |
(nc -l 8080 <&0 & echo $! > nc_pid; wait) > >(
︙
(読みやすくするために、末尾を別々の行に分割しました|
)まで待つのです。 (実際には、コマンドを前景に戻します。)スコット <&0
非同期プロセスがスクリプトから正しい標準入力を読み取るようにするためのヒントです。
しかし、なぜ「猫」を使うのですか??そして> >(…)
単純パイプの代わりになぜ使用しましたか??
これは次のように単純化できます。
本当ではありますが する (nc -l 8080 < /var/run/out & echo $! > nc_pid; 待機) | 行を読むとき する 何かをしなさい 完璧 完璧
nc
直接読み、/var/run/out
プロセスの置き換えの代わりに単純なパイプを使用してください。
答え2
私が考えることができる最も簡単な方法は、プロセスを開始する前にpidを取得することです。
たとえば(Bashから):
pidfile() { (
echo $BASHPID > "$1"
shift
exec "$@"
) }
mkfifo /var/run/out
while true
do
pidfile /tmp/cat.pid cat /var/run/out | pidfile /tmp/nc.pid nc -l 8080 > >(
while read line
do
do some stuff
done
)
done
pidfile
これにより、現在のPIDを指定されたファイルに書き込み、残りのパラメータを使用して実行する関数が生成されますexec
。これexec
により、ファイルを作成したシェルと同じpidでコマンドが実行されます。
サブシェルで実行するためにpidfile()
関数全体を括弧で囲みます。()
パイプラインにないコマンドを実行する場合、これは非常に重要です。たとえば、
pidfile /tmp/foo some command here
これはpidfile()
スクリプトの残りの部分と同じプロセスで実行されるため、呼び出されると実行中exec
のコマンドはPIDを引き継ぎ、スクリプトは実行されなくなります。
また、上記はbash用に書かれています。$BASHPID
bash 特定の変数です。$$
これはサブシェルを使用しても変更されないため、この値は私たちの使用には適していません。
答え3
cat
またはPIDを取得できません。nc
そのスクリプトからそうでなければバックステージコースそして&
。バックグラウンドに含まれていないすべてのプロセスはバックグラウンドに含める必要があります。終わるスクリプトが続く前に。
これBash Wikiプロセス管理記事これらのことを賢明に行う方法について説明します。