V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
yadam
V2EX  ›  问与答

bash 中的&符号能否一直保持后台运行的疑问

  •  
  •   yadam · 2015-01-26 16:46:56 +08:00 · 4236 次点击
    这是一个创建于 3581 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题是: &字符能否保持ssh的session结束之后 一直 运行?
    一直对搜这种特殊字符无能, Google了关键字 ssh Ampersand 换了几个描述也没找到想要的答案.搜到的基本全是怎么样nohup和&结合的描述


    软件没有写成守护进程,但是还想后台运行, 一直以来用的是screen, 最近使用 "./app & " 这种方式启动,发现软件会退出, 所以想排除这种使用方式的问题.

    第 1 条附言  ·  2015-01-27 16:22:29 +08:00
    多谢各位指导, 综合几位的答案如下, 请各位看看有没有错误或者漏的地方:
    ❤判断SSH退出后子进程是否会被关闭有以下几种情况:

    1. 如果打开了huponexit,所有的子进程在SSH退出后全都会接到SIGHUP信号,除非程序自己处理
    SIGHUP信号并且不退出,否则程序退出
    2. huponexit打开时,可以使用nohup或者disown使进程不退出.原理是nohup捕获了SIGHUP信号,disown是告诉SHELL不给程序发送SIGHUP信号
    3. huponexit没有打开时,如果SSH正常logout,后台子进程不会自己退出
    4. huponexit没有打开时,如果SSH非正常退出(比如断网,强行关闭SSH软件),所有子进程都会被kill
    5. 正确的使用screen也可以防止子进程在SSH断开时退出

    ❤查看huponexit是否打开的方法
    shopt | grep huponexit

    ❤&是干什么用的?
    man bash可以看到如下描述

    If a command is terminated by the control operator &, the shell executes the command in the background in a subshell. The shell does not wait for the command to finish, and the return status is 0.

    ❤为什么nohup有时要和&一起使用?
    man nohup可以看到下面这句

    'nohup' does not automatically put the command it runs in the background; you must do that explicitly, by ending the command line with an `&'.

    ❤参考

    http://hacktux.com/bash/ampersand
    http://stackoverflow.com/questions/15595374/whats-the-difference-between-nohup-and-ampersand
    http://stackoverflow.com/questions/4298741/how-bash-handles-the-jobs-when-logout
    http://superuser.com/questions/662431/what-exactly-determines-if-a-backgrounded-job-is-killed-when-the-shell-is-exited

    @wzxjohn @66450146 @kslr @rrfeng @meta @Tink @whuhacker @atupal @ryd994 @lululau
    11 条回复    2015-01-26 20:33:30 +08:00
    wzxjohn
        1
    wzxjohn  
       2015-01-26 16:49:25 +08:00 via iPhone   ❤️ 1
    nohup 一起用确实可以,不过你有 screen 为何不用。。。一直都用 screen 的路过。。。
    66450146
        2
    66450146  
       2015-01-26 16:51:16 +08:00   ❤️ 1
    还是用 screen / tmux 吧……
    kslr
        3
    kslr  
       2015-01-26 16:57:54 +08:00   ❤️ 2
    & 大致意思是利用SHELL的技巧,新建不属于当前终端的进程,这样终端关闭的信号就不会影响到。
    这里有一篇文章:
    http://www.ibm.com/developerworks/cn/linux/l-cn-nohup/
    rrfeng
        4
    rrfeng  
       2015-01-26 16:59:09 +08:00   ❤️ 1
    bash 默认设置 shopt huponexit 是 off 的。
    所以 cmd & 可以一直后台运行,exit ssh 也没有影响。

    但是,强行断开 ssh 连接,也就是非常规的 exit 比如网络断了之类的,还是会终止。

    使用 nohup 执行,则异常断开也可以保持后台运行。

    还有 setsid 和 disown 方式。
    meta
        5
    meta  
       2015-01-26 17:02:40 +08:00   ❤️ 1
    如果你的程序不会向标准输出和错误输出写任何东西就可以一直运行,否则的话因为你已经把这两个输出关闭掉了,一般会出错退出。
    你可以在程序内部处理,把这两个输出重定向,或者在shell中重定向。比如 > xxx.log 2>&1。如果用nohup的话,默认会重定向到nohup.out
    Tink
        6
    Tink  
       2015-01-26 17:08:10 +08:00 via iPhone   ❤️ 1
    nohup command &
    rrfeng
        7
    rrfeng  
       2015-01-26 17:22:08 +08:00   ❤️ 1
    对,还有一个就是有些程序会判断 stdout/stderr 是否可用。否则会自行关闭。
    方法是加上 &> /tmp/log 或者 /dev/null 重定向掉
    whuhacker
        8
    whuhacker  
       2015-01-26 19:10:38 +08:00   ❤️ 1
    pstree 查看一下进程树,就知道 ssh 进程下的子进程,在你断开 ssh 连接后都会被杀掉
    而 screen / tmux 会把进程都挪出 ssh 的魔爪……
    atupal
        9
    atupal  
       2015-01-26 19:23:33 +08:00   ❤️ 1
    我一般都
    $ (./xxx.sh 1>stdout.log 2>error.log & )

    然后就是在 后台运行且 挂到 init 进程下,

    要看输出就
    $ tail -f stdout.log

    要看 错误就
    $ tail -f error.log
    ryd994
        10
    ryd994  
       2015-01-26 20:27:06 +08:00 via Android   ❤️ 1
    其实还是screen好用啊
    lululau
        11
    lululau  
       2015-01-26 20:33:30 +08:00   ❤️ 2
    @meta 👍大多数人知道 SIGHUP 可能会使程序终止,而不知道往一个已经关闭了的文件写入数据也可能会使进程终止。hohup 其实有两个作用,一是将进程的SIGHUP handler 设为 IGNORE,二是重定向标准输出和标准错误。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1020 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 22:39 · PVG 06:39 · LAX 14:39 · JFK 17:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.