私はnc
bashを使って簡単なWebサーバーを書いています。次のようになります。
#!/bin/bash
rm -f /var/run/streamman/out
mkfifo /var/run/streamman/out
trap "rm -f /var/run/streamman/out" EXIT
while true
do
cat /var/run/streamman/out | nc -l 8080 > >( # parse the netcat output, to build the answer redirected to the pipe "out".
while read line
do
line=$(echo "$line" | tr -d '[\r\n]')
if echo "$line" | grep -qE '^GET /\?action' # if line starts with "GET /"
then
action=$(echo "$line" | cut -d '=' -f2 | cut -d ' ' -f1 | cut -d '&' -f1) # extract the request
query_str=$(echo "$line" | cut -d '&' -f 2-)
args=$(query_string_to_args $query_str)
fn_exists $action && eval ${action} ${args} || echo "No route for $action"
elif [ "x$line" = x ] # empty line / end of request
then
header=$(cat /var/www/header.html)
footer=$(cat /var/www/footer.html)
echo "$header somecontent $footer" > /var/run/streamman/out
fi
done
)
done
いくつかの追加機能がありますが、簡潔にするために省略しました。
次のinit
スクリプトを使用してデーモンから始めます。
#!/bin/bash
user=streamman
name=streamman-httpd
prog=/usr/sbin/streamman-httpd
case $1 in
start)
start-stop-daemon --start --user $user --chuid $user --background --umask 0000 --exec $prog > /var/log/streamman/streamman.log 2>&1
;;
stop)
/sbin/start-stop-daemon --stop --user "$user" --name "$name" --retry=TERM/5/KILL/1
;;
restart)
;;
*)
;;
esac
ps afx
サービスを開始した後の出力は次のとおりです。
3023 ? S 0:00 /bin/bash /usr/sbin/streamman-httpd
3065 ? S 0:00 \_ nc -l 8080
3066 ? S 0:00 \_ /bin/bash /usr/sbin/streamman-httpd
ご覧のとおり、何らかの理由でサブプロセスが開始されました。私はそれが私がそれを使ってパイプという名前を付けた方法に関連していると思いますnc
。
これでサービスを停止しようとすると、次のメッセージが表示されます。
Program streamman-httpd, 1 process(es), refused to die.
出力ps afx
:
3065 ? S 0:00 nc -l 8080
3066 ? Z 0:00 \_ [streamman-httpd] <defunct>
何らかの理由で子プロセスは終了しません。
pidファイルを試しましたが、サーバースクリプトを出力できませんでした。子供たちpidをファイルに追加します。
両方のプロセスを終了するにはどうすればよいですか?
答え1
主な理由は、「start」セクションの「exec」呼び出しによるものだと思います。trap "rm -f /var/run/streamman/out" EXIT
文字列に次のようなものを追加できますか?
; ps ax | kill `awk '$5 ~ /nc -l 8080/ {print $1}`
私はこれが汚い解決策であることを知っています...