如何使用 start-stop-daemon 终止子进程?

如何使用 start-stop-daemon 终止子进程?

我正在使用ncbash 编写一个简单的网络服务器。它看起来像这样:

#!/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

我认为主要原因是“开始”部分中的“exec”调用。您可以在trap "rm -f /var/run/streamman/out" EXIT字符串中添加类似以下内容吗?

; ps ax | kill `awk '$5 ~ /nc -l 8080/ {print $1}`

我知道这是一个肮脏的解决方法......

相关内容