想让 PHP cli 执行一个较长的任务, xshell 一关闭, nohup 也跟着退出了,怎么回事? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
alwayshere

想让 PHP cli 执行一个较长的任务, xshell 一关闭, nohup 也跟着退出了,怎么回事?

  •  
  •   alwayshere 2017 年 3 月 16 日 6149 次点击
    这是一个创建于 3328 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前用 php cli 模式爬取一个网站内容,因为要执行很久,在 xshell 中输入:

    nohup php scrape.php &

    回车后, php 继续执行,但是一关闭 xshell ,这个进程也就跟着结束了, nohup 这么脆弱吗? Linux 小白不太懂,求好心 V2 们解答一下,或者有没有更好的让 php 常驻进程的命令?

    第 1 条附言    2017 年 3 月 16 日
    刚刚手上三台服务器测试了一下,其中两台服务器 xshell 右上角叉叉关闭了, nohup 进程继续执行,另外一台服务器 xshell 右上角叉叉关闭后, nohup 进程终止,但是如果在 xshell 中 exit 后,再右上角叉叉, nohup 进程却能继续存活,这是何解?三台服务器都是 centos 6.8
    27 条回复    2017-03-16 23:44:20 +08:00
    emuhuang
        1
    emuhuang  
       2017 年 3 月 16 日
    at ?
    torbrowserbridge
        2
    torbrowserbridge  
       2017 年 3 月 16 日 via iPhone
    screen / tmux
    alwayshere
        3
    alwayshere  
    OP
       2017 年 3 月 16 日
    @emuhuang 什么意思?
    loading
        4
    loading  
       2017 年 3 月 16 日 via Android
    2 楼 +1
    gouchaoer
        5
    gouchaoer  
       2017 年 3 月 16 日
    不可能,你先开 error_log 或者 coredump 把原因搞清楚
    gouchaoer
        6
    gouchaoer  
       2017 年 3 月 16 日
    http://www.bo56.com/一个 echo 引起的进程崩溃 /
    spkinger
        7
    spkinger  
       2017 年 3 月 16 日
    用 Supervisor 守护进程,挂了它会尝试重启
    Hello1995
        8
    Hello1995  
       2017 年 3 月 16 日 via Android
    screen 。另外,如果就一台机器长时间在抓,不用高匿代理访问很容易被拉黑……
    lcdtyph
        9
    lcdtyph  
       2017 年 3 月 16 日
    不想麻烦的话就
    setsid nohup php scrape.php &
    Biny
        10
    Biny  
       2017 年 3 月 16 日
    dnf install screen
    elarity
        11
    elarity  
       2017 年 3 月 16 日
    <?php
    // fork 一个 php 进程
    $pid = pcntl_fork();
    if ($pid < 0)
    exit(' fork error. ');
    else if ($pid)
    exit(' I am the parent process ');
    else {
    // I am the child process
    $sid = posix_setsid();
    if ($sid < 0)
    exit;
    for($i = 0; $i <= 60; $i++) {
    echo "echo Hello world from PHP daemon.".PHP_EOL;
    sleep(5);
    }
    }



    使用 posix_setsid 是至关重要的一步了,上面的代码助你完成 php 脚本 daemon 的完成,不需要借助其他力量,注意骚年,不要搞成僵尸进程
    iyaozhen
        12
    iyaozhen  
       2017 年 3 月 16 日 via Android
    但是一关闭 xshell ,这个进程也就跟着结束了
    不肯能啊,我一直这样用,一般场景你这种做法就行了。是不是 PHP 自己报错了
    w3sy
        13
    w3sy  
       2017 年 3 月 16 日
    http://www.cnblogs.com/allenblogs/archive/2011/05/19/2051136.html
    我才发现我和他操作终端时的一个细节不同:他是在当 shell 中提示了 nohup 成功后还需要按终端上键盘任意键退回到 shell 输入命令窗口,然后通过在 shell 中输入 exit 来退出终端;而我是每次在 nohup 执行成功后直接点关闭程序按钮关闭终端.。所以这时候会断掉该命令所对应的 session ,导致 nohup 对应的进程被通知需要一起 shutdown 。
    gouchaoer
        14
    gouchaoer  
       2017 年 3 月 16 日
    @elarity 教科书般的错误,你需要 2 次 fork 。。。参考这个: https://yangxikun.github.io/linux/2013/11/11/linux-process.html
    alwayshere
        15
    alwayshere  
    OP
       2017 年 3 月 16 日
    @iyaozhen 我手上另外两台服务器都可以 xshell 关闭后, nohup 继续执行,就这个装一样的 centos 6.8 系统, xshell 一关闭,马上就退出 php 进程,测试了好多次都是这样,必须把 xshell 挂起
    elarity
        16
    elarity  
       2017 年 3 月 16 日
    @gouchaoer yes ! I know , 我直接从 posix_setsid 的手册下搞过来这段 code ,旨在告诉小朋友 setsid ,多谢指正,误导了不少好骚年
    SummerWQM
        17
    SummerWQM  
       2017 年 3 月 16 日
    这种建议 使用 supervisord 吧
    lululau
        18
    lululau  
       2017 年 3 月 16 日
    5L +1
    TIGERB
        19
    TIGERB  
       2017 年 3 月 16 日
    tmux
    HowToMakeLove
        20
    HowToMakeLove  
       2017 年 3 月 16 日
    nohup command & 后,需要敲回车退出到 bash 、然后再退出
    alwayshere
        21
    alwayshere  
    OP
       2017 年 3 月 16 日
    @HowToMakeLove 我是这样做的,连按两次回车,直接右上角关闭 xshell ,然后那个 php 进程也立即终止了
    simple2025
        22
    simple2025  
       2017 年 3 月 16 日
    screen?
    minbaby
        23
    minbaby  
       2017 年 3 月 16 日
    这种需求有这么几种做法
    1. tmux/screen/byobu(简单)这些工具,可以吧你正在用的会话一直保持下去
    2. 使用 supervisor 这类守护进程工具,可以帮助你自己启动,或者重新启动程序(推荐)
    3. 自己实现 daemon 功能(参考 https://github.com/minbaby/http-server-learning/blob/master/sample/how_to_make_daemon/daemon.php)
    Jaylee
        24
    Jaylee  
       2017 年 3 月 16 日
    @minbaby 两次 fork
    minbaby
        25
    minbaby  
       2017 年 3 月 16 日
    @Jaylee 翻了一下 unix 环境编程的 守护进程那一章,确实是进行了两次 fork ,不过中间有提到, System V 系统有人建议进行两次 fork ,以防止其获取终端控制。不过这似乎并不是必须的吧?
    FurN1
        26
    FurN1  
       2017 年 3 月 16 日
    screen
    eoo
        27
    eoo  
       2017 年 3 月 16 日 via Android
    pm2
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3012 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 71ms UTC 14:10 PVG 22:10 LAX 07:10 JFK 10:10
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86