AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 705548
Accepted
DroidOS
DroidOS
Asked: 2015-12-04 08:24:25 +0800 CST2015-12-04 08:24:25 +0800 CST 2015-12-04 08:24:25 +0800 CST

从 /etc/init.d 启动的 Ubuntu 服务以错误的 PID 结束

  • 772

这个问题是我上一个问题的后续问题。回顾一下

  • 我想在我的 Ubuntu 14.04 服务器上使用 OpenResty 而不是普通的 Nginx。
  • 我已经按照此处的说明编译了 OpenResty 。
  • 编译nginx结束在`/usr/local/openresty/nginx/sbin'
  • 我现在可以./nginx从该文件夹启动 nginx。

问题是如果我使用通过etc安装的 Nginx 的香草版本,我需要有能力做一些事情,就像service nginx status|reload|start|stop我通常会做的那样。apt-get install nginx|nginx-extras

我对这些问题的了解是非常基本的。但是,通过破解由此处描述的想法/etc/init.d/nginx创建的脚本apt-get install nginx并修改此处描述的想法,我创建了自己的/etc/init.d/nginx脚本,我在下面复制了该脚本

#!/bin/sh

NAME="nginx"
PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
APP="/usr/local/openresty/nginx/sbin/nginx"

if [ -r /etc/default/nginx ]; then
 . /etc/default/nginx
fi

. /lib/init/vars.sh
. /lib/lsb/init-functions

PID=$(cat /usr/local/openresty/nginx/conf/nginx.conf | grep -Ev '^\s*#' | 
awk 'BEGIN { RS="[;{}]" } { if ($1 == "pid") print $2 }' | head -n1)
if [ -z "$PID" ]
then
   PID=/var/run/nginx.pid
fi

if [ -n "$ULIMIT" ]; then
 ulimit $ULIMIT
fi

start() {
 printf "Starting '$NAME'... "
 start-stop-daemon --start --background --make-pidfile --pidfile    
 /var/run/$NAME.pid --exec "$APP"
 printf "done\n"
}

killtree() {
 local _pid=$1
 local _sig=${2-TERM}
 for _child in $(ps -o pid --no-headers --ppid ${_pid}); do
    killtree ${_child} ${_sig}
 done
 kill -${_sig} ${_pid}
}

stop() {
 printf "Stopping '$NAME'... "
 [ -z `cat /var/run/$NAME.pid 2>/dev/null` ] || \
 while test -d /proc/$(cat /var/run/$NAME.pid); do
  killtree $(cat /var/run/$NAME.pid) 15
  sleep 0.5
 done 
 [ -z `cat /var/run/$NAME.pid 2>/dev/null` ] || rm /var/run/$NAME.pid
 printf "done\n"
}

case "$1" in
 start)
   start
   ;;
 stop)
  stop
  ;;
 restart)
  stop
  start
  ;;
reload)
  start-stop-daemon --stop --signal HUP --quiet --pidfile /var/run/nginx.pid 
  --name nginx
  ;;            
status)
 status_of_proc -p /var/run/nginx.pid "nginx" "nginx" && exit 0 || exit $?
    ;;

*)
 echo "Usage: $NAME {start|stop|restart|reload|status}" >&2
 exit 1
 ;;
esac

exit 0

有了这个,如果我重新启动我的服务器并发出一个lsof -nP -i | grep LISTEN我得到输出

nginx     2247     root    6u  IPv4  14166      0t0  TCP *:80 (LISTEN)
nginx     2248   nobody    6u  IPv4  14166      0t0  TCP *:80 (LISTEN)

我在这里不明白的一件事 - 为什么有两个用户:root 和 nobody?因此,如果我从浏览器访问服务器并执行 PHP 脚本,它将以 - nobody,root ... 运行?

我检查了/var/run/nginx.pid。那里记录的 PID 是2146,即比上面和我运行时报告的少1 netstat -anp | grep 80。

我多次尝试最后一步 - 多次重新启动 - 结果总是一样。自然地,这意味着随后尝试重新加载或停止 Nginxservice nginx reload并service nginx stop失败:WRONG PID!

当我手动编辑/var/run/nginx.pid以确保它具有正确的PID 时,一切都按预期工作。

我不得不承认,我的工作超出了我对这些问题在这里如何运作的了解。如果能帮助解决我在这里遇到的问题,我将不胜感激。

14.04
  • 1 1 个回答
  • 1151 Views

1 个回答

  • Voted
  1. Best Answer
    DroidOS
    2015-12-04T13:04:10+08:002015-12-04T13:04:10+08:00

    我在这里发布答案,希望它能帮助其他人避免我不得不忍受的挫败感。这里最容易处理的问题是nobody我上面提到的用户。发生这种情况很简单,因为nginx.confopenresty 创建的文件 - 请参阅

    /usr/local/openresty/nginx/conf/nginx.conf

    不费心指定用户。只需编辑第一行

    #user nobody所以它读取user www-data www-data并且该特定问题已排序。

    第二个问题是init.d剧本。恐怕openresty文档要在这里背锅了。他们竭尽全力解释如何获得 openresty 以及如何编译它。关于如何对其进行守护进程的几句话不会出错。

    在黑暗中摸索了几个小时后,我想到了寻找openresty init.d。第一个出现的结果就是这个。我在下面重现该脚本

    #!/bin/sh
    
    
    PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
    DESC="Nginx Daemon"
    NAME=nginx
    PREFIX=/usr/local/openresty/nginx
    DAEMON=$PREFIX/sbin/$NAME
    CONF=$PREFIX/conf/$NAME.conf
    PID=$PREFIX/logs/$NAME.pid
    SCRIPT=/etc/init.d/$NAME
    
    . /lib/lsb/init-functions
    
    if [ ! -x "$DAEMON" ] || [ ! -f "$CONF" ]; then
     echo -e "\033[33m $DAEMON has no permission to run. \033[0m"
     echo -e "\033[33m Or $CONF doesn't exist. \033[0m"
     sleep 1
     exit 1
    fi
    
    do_start() {
     if [ -f $PID ]; then
        echo -e "\033[33m $PID already exists. \033[0m"
        echo -e "\033[33m $DESC is already running or crashed. \033[0m"
        echo -e "\033[32m $DESC Reopening $CONF ... \033[0m"
        $DAEMON -s reopen -c $CONF
        sleep 1
        echo -e "\033[36m $DESC reopened. \033[0m"
     else
        echo -e "\033[32m $DESC Starting $CONF ... \033[0m"
        $DAEMON -c $CONF
        sleep 1
        echo -e "\033[36m $DESC started. \033[0m"
     fi
    }
    
    do_stop() {
     if [ ! -f $PID ]; then
        echo -e "\033[33m $PID doesn't exist. \033[0m"
        echo -e "\033[33m $DESC isn't running. \033[0m"
     else
        echo -e "\033[32m $DESC Stopping $CONF ... \033[0m"
        $DAEMON -s stop -c $CONF
        sleep 1
        echo -e "\033[36m $DESC stopped. \033[0m"
     fi
    }
    
    do_reload() {
     if [ ! -f $PID ]; then
        echo -e "\033[33m $PID doesn't exist. \033[0m"
        echo -e "\033[33m $DESC isn't running. \033[0m"
        echo -e "\033[32m $DESC Starting $CONF ... \033[0m"
        $DAEMON -c $CONF
        sleep 1
        echo -e "\033[36m $DESC started. \033[0m"
     else
        echo -e "\033[32m $DESC Reloading $CONF ... \033[0m"
        $DAEMON -s reload -c $CONF
        sleep 1
        echo -e "\033[36m $DESC reloaded. \033[0m"
     fi
    }
    
    do_quit() {
     if [ ! -f $PID ]; then
        echo -e "\033[33m $PID doesn't exist. \033[0m"
        echo -e "\033[33m $DESC isn't running. \033[0m"
     else
         echo -e "\033[32m $DESC Quitting $CONF ... \033[0m"
         $DAEMON -s quit -c $CONF
         sleep 1
         echo -e "\033[36m $DESC quitted. \033[0m"
      fi
    }
    
    do_test() {
     echo -e "\033[32m $DESC Testing $CONF ... \033[0m"
     $DAEMON -t -c $CONF
    }
    
    do_info() {
     $DAEMON -V
    }
    
    case "$1" in
     start)
      do_start
      ;;
     stop)
      do_stop
      ;;
     reload)
      do_reload
      ;;
     restart)
      do_stop
      do_start
      ;;
    status)
        status_of_proc -p $PID "$DAEMON" "$NAME" && exit 0 || exit $?
        ;;
     quit)
      do_quit
      ;;
     test)
      do_test
      ;;
     info)
      do_info
      ;;
     *)
      echo "Usage: $SCRIPT {start|stop|reload|restart|quit|test|info}"
      exit 2
      ;;
     esac
    
     exit 0
    

    我已更正原始脚本中的遗漏 - 没有status方法。

    • 1

相关问题

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve