nohup

问题引出:这几天遇到一个问题,调用别人写的nginx啊、logstash啊等等一些启动脚本(如:nginx_start.sh)的时候,ps查看了一下进程,发现应用起来后,启动脚本的进竟然也还在,看了一下脚本,里面用nohup方法,理论上进程起来后,启动脚本的进程不应该还在才对,针对这个现象,自己做了一些测试。


一、模仿写了一个nginx“启动”脚本,如下:

#!/bin/bash

## 状态信息
nginx_status()
{
    # 查看状态
    if [ "x${pid}" != "x" ]; then
        echo "nginx (PID:$(echo -n ${pid})) is running..."
    else
        echo "nginx was stopped"
    fi
}

nginx_start()
{
    # 判断是否已启动
    [ "x${pid}" = "x" ] && nohup sleep 300 &
    sleep 1

    nginx_status
}

if [ "$USER" = "root" ]; then
    case $1 in
        start)
            nginx_start
            ;;
        status)
            nginx_status
            ;;
        *)
            echo "nothing"
    esac
else
    echo "User is $USER. You must be apps to run this script!"
fi

2、执行这个进程,出现如下的结果:启动进程尽然还在。

pstree查看一下:


3、多次测试,排除了启动脚本中sleep 1、后面调用nginx_status和最后的case的可能性。(这里测试过程比较简单,略)

4、多次测试,排除一些可能性后,再研究启动脚本的写法,

理论上来说,使用nohup &会进入后台执行,并不会影响父进程的正常退出,为了验证这个,做了如下尝试:

执行后发现:并不会出现启动脚本的进程。


5、这样,就把问题集中到了nohup &前面的语句了,仔细的想了一下,[ "x${pid}" = "x" ] && nohup sleep 300 &  这条语句,会不会是最后的&将命令放入后台执行的时候失败了,也就是会所这条语句并没有像预想中的那样进入后台执行,即进入后台“失败”,没有真正意义上的进入后台,从而影响了父进程的正常退出,这里只需要把sleep 300放入后台进行就可以了,为了排除前面可能带来的干扰,做了如下测试:

结果发现:启动脚本的进程没有了,也就是说sleep 300放入后台执行并没有影响父进程的退出。


6、上面的测试中,进入后台运行的程序都是需要执行一定时间或者是一直在执行的(引出这些测试的例子就是这种类型),那么如果是进入后台执行的程序很快就能执行完,结果会怎样?

运行结果:并没有发现启动脚本的进程


二、总结:

个人总结:查看一下资料后,个人觉得原因可能如下:nohup  &的执行依赖于前面[ "x${pid}" = "x" ] 的执行结果为真,即进入后台的程序依赖了父进程的一些资源,例如文件资源等,所以在子进程(后台进程)没有运行结束之前(文中模仿的就是进入后台的子进程还在运行中),这些依赖的资源没有被释放,导致父进程无法正常退出,一旦子进程执行完后(文中sleep 300后)依赖的父进程的资源释放后,父进程正常退出。

求其他高见。谢谢




















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值