【问题标题】:How to create PID for forked process in init script?如何在初始化脚本中为分叉进程创建 PID?
【发布时间】:2015-08-19 16:12:36
【问题描述】:

我知道问题出在哪里,但我不确定什么是好的解决方案。

所以,我有一个 uwsgi 进程,用于 Graphite 与 Nginx 一起使用。以下是一些背景信息:

我从 pip 安装了 uwsgi,并使用 -configfile (.ini) 运行 uwsgi:

[uwsgi]
processes = 1
socket = 127.0.0.1:3031
gid = root
uid = root
chdir = /opt/graphite/conf
daemonize = /var/log/graphite/uwsgi.log
#pidfile = /var/run/uwsgi.pid
module = wsgi:application

我有一个初始化脚本,它执行以下操作(我在互联网上找到它,但没有完成):

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="uwsgi daemon"
NAME=uwsgi
DAEMON=/usr/local/bin/uwsgi
CONFIGFILE=/opt/graphite/conf/$NAME.ini
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

set -e
[ -x "$DAEMON" ] || exit 0

start() {
    if [ -f "$PIDFILE" ];then
       echo "${NAME} Service already running" >&2
       return 1
    fi
    echo "Starting $NAME" >&2
    $DAEMON $CONFIGFILE || echo -n "uwsgi already running"     
}

stop() {
    $DAEMON --stop $PIDFILE || echo -n "uwsgi not running"
    rm -f $PIDFILE
    echo "$DAEMON STOPPED."
}

情况如下:如果我有 .ini 文件创建 PID - 它会提供与实际 PID 甚至不相近的进程 ID。它的工作方式,正如我发现的那样,uwsgi 启动然后获取配置文件并守护进程。所以,如果我要使用类似

的东西
ps -ef |awk '/[u]wsgi/{print $2}' > $PIDFILE

它将有 2 个进程 ID。例如

cat /opt/uwsgi/uwsgi.ini
4121
4141

现在第二个PID#是实际运行的进程。

如何使用 awk 命令获取 PID,然后将其剪切,以便我只用第二个 # 触摸 PIDFILE?

我不确定要使用什么命令。有什么想法吗?

【问题讨论】:

  • 不能保证永远是第二个。我假设父母会退出,孩子会坚持,但情况可能相反。无论如何,检查父母,然后决定要捕获哪一个。

标签: bash shell uwsgi init pid


【解决方案1】:

我没有在寻找正确的关键字或其他东西,但我在这里找到了答案: How to use SED to print a specific line

所以,我所做的是添加 | sed -n '2p' 到我的 init 脚本,我得到了将正确的 PID 输入到 /var/run/.pid 进程的脚本。

我的初始化脚本如下:

#! /bin/sh

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="uwsgi daemon"
NAME=uwsgi
DAEMON=/usr/local/bin/uwsgi
CONFIGFILE=/opt/graphite/conf/$NAME.ini
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

set -e
[ -x "$DAEMON" ] || exit 0

start() {
    if [ -f "$PIDFILE" ];then
       echo "${NAME} Service already running" >&2
       return 1
    fi
    echo "Starting $NAME" >&2
    $DAEMON $CONFIGFILE || echo -n "uwsgi already running"
    sleep 2
    ps -ef |awk '/[u]wsgi/{print $2}'| sed -n '2p' > $PIDFILE
}

stop() {
    if [ ! -f "$PIDFILE" ]; then
       echo "${NAME} Service not running" >&2
       return 1
    fi
    $DAEMON --stop $PIDFILE || echo -n "uwsgi not running"
    rm -f $PIDFILE
    echo "$DAEMON STOPPED."
}

status() {
    ps aux |grep $DAEMON |sed -n '1p'
}

case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  status)
    status
    ;;
  restart)
    stop
    sleep 1
    start
    ;;
  *)
    echo "Usage: $0 {start|stop|restart|status}"
esac

【讨论】:

  • 这有一个明显的问题,即您正在对第二个实例进行硬编码,这可能并不总是正确的。请参阅我的评论,以获得更强大的方法。
  • Triplee - 花了我一点时间来解决这个问题,但你是对的,谢谢你的帮助!
猜你喜欢
  • 2014-09-17
  • 2022-01-05
  • 1970-01-01
  • 1970-01-01
  • 2013-01-23
  • 1970-01-01
  • 1970-01-01
  • 2014-10-10
相关资源
最近更新 更多