Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell 如何将已经运行的进程置于nohup下?_Shell_Nohup - Fatal编程技术网

Shell 如何将已经运行的进程置于nohup下?

Shell 如何将已经运行的进程置于nohup下?,shell,nohup,Shell,Nohup,我有一个进程已经运行了很长时间,不想结束它 如何将其置于nohup下(即,即使关闭终端,如何使其继续运行?将正在运行的作业与shell分离的命令(=使其成为nohup)是disown和基本shell命令 从bash手册页(manbash): 拒绝[-ar][h][jobspec…] 如果没有选项,将从活动作业表中删除每个作业规范。如果给出了-h选项,则每个jobspec都不可用 已从表中删除,但进行了标记,以便在shell收到SIGHUP时不会将SIGHUP发送到作业。如果没有作业规范 当前,并

我有一个进程已经运行了很长时间,不想结束它


如何将其置于nohup下(即,即使关闭终端,如何使其继续运行?

将正在运行的作业与shell分离的命令(=使其成为nohup)是
disown
和基本shell命令

从bash手册页(manbash):

拒绝[-ar][h][jobspec…]

如果没有选项,将从活动作业表中删除每个作业规范。如果给出了-h选项,则每个jobspec都不可用 已从表中删除,但进行了标记,以便在shell收到SIGHUP时不会将SIGHUP发送到作业。如果没有作业规范 当前,并且既不提供-a选项也不提供-r选项,则使用当前作业。如果未提供jobspec,则-a选项 指移除或标记所有作业;没有jobspec参数的-r选项将操作限制为运行的作业。回归 值为0,除非作业规范未指定有效作业

这意味着,一个简单的

disown -a
将从作业表中删除所有作业,并使用bash将进程发送到后台,使其成为nohup

  • Ctrl+Z停止(暂停)程序并返回shell
  • bg
    在后台运行
  • disown-h[job spec]
    其中[job spec]是作业编号(如第一个运行作业的
    %1
    ;使用
    jobs
    命令查找您的编号),以便在终端关闭时不会终止作业

  • 以上都是很好的答案,我只想补充一点:

    您不能
    disown
    一个pid或流程,您可以
    disown
    一个作业,这是一个重要的区别

    作业是附加到shell的进程的概念,因此您必须将作业扔到后台(而不是挂起它),然后拒绝它

    问题:

    %  jobs
    [1]  running java 
    [2]  suspended vi
    %  disown %1
    
    看 有关Unix作业控制的更详细讨论。

    假设由于某种原因Ctrl+Z也不工作,请转到另一个终端,找到进程id(使用
    ps
    )并运行:


    SIGSTOP
    将暂停进程,而
    SIGCONT
    将在后台恢复进程。所以现在,关闭两个终端不会停止进程

    不幸的是,
    disown
    是bash特有的,并非在所有shell中都可用

    某些风格的Unix(例如AIX和Solaris)在
    nohup
    命令本身上有一个选项,可以应用于正在运行的进程:

    nohup -p pid
    

    请参见将正在运行的进程发送到nohup()

    nohup-ppid
    ,它对我不起作用

    然后我尝试了以下命令,效果非常好

  • 运行一些命令, 说
    /usr/bin/python/vol/scripts/python\u scripts/retention\u all\u properties.py 1

  • Ctrl+Z停止(暂停)程序并返回shell

  • bg
    在后台运行

  • disown-h
    ,以便在终端关闭时不会终止进程

  • 键入
    exit
    退出shell,因为现在您可以开始了,因为操作将在其自己的进程中在后台运行,因此它不会绑定到shell


  • 这个过程相当于在我的AIX系统上运行
    nohupsomecommand

    ,我尝试过

    nohup -p  processid>
    

    这很有效。即使在关闭终端窗口后,它仍继续运行我的进程。我们使用ksh作为默认shell,因此
    bg
    disown
    命令不起作用。

    节点的答案非常好,但它留下了如何重定向stdout和stderr的问题。我在上找到了一个解决方案,但它也不完整。我想合并这两种解决方案。这是:

    在我的测试中,我制作了一个名为loop.sh的小bash脚本,它在无限循环中以一分钟的睡眠打印自己的pid

    $./loop.sh
    
    现在以某种方式获取此过程的PID。通常
    ps-C loop.sh
    就足够了,但它是在我的箱子里打印出来的

    现在我们可以切换到另一个终端(或在同一终端中按^Z和)。现在应将
    gdb
    附加到此流程

    $ gdb -p <PID>
    
    Close(1)在成功时返回零

    (gdb) call open("loop.out", 01102, 0600)
    $6 = 1
    
    如果成功,Open(1)将返回新的文件描述符

    此打开等同于
    打开(路径,O|u TRUNC | O|u create | O|u RDWR,S|u IRUSR | S|u IWUSR)
    。 只能应用
    /usr/sbin/lsof
    而不是
    O_-RDWR
    ,但是
    /usr/sbin/lsof
    为所有std*文件处理程序(
    FD
    列)显示“u”,即
    O_-RDWR

    我检查了/usr/include/bits/fcntl.h头文件中的值

    输出文件可以使用
    O_APPEND
    打开,正如
    nohup
    所做的那样,但是
    man open(2)
    不建议这样做,因为可能存在NFS问题

    如果返回值为-1,则
    call perror(“”
    打印错误消息。如果我们需要errno,请使用
    p errno
    gdb命令

    现在我们可以检查新重定向的文件<代码>/usr/sbin/lsof-p打印:

    loop.sh <PID> truey    1u   REG   0,26        0 15008411 /home/truey/loop.out
    
    如果脚本被另一个终端的
    gdb
    停止,它将继续运行。我们可以切换回loop.sh的终端。现在它不向屏幕写入任何内容,而是运行并写入文件。我们必须把它放在背景中。所以按
    ^Z

    ^Z
    [1]+  Stopped                 ./loop.sh
    
    (现在我们处于相同的状态,就好像开始时按下了
    ^Z

    现在,我们可以检查作业的状态:

    $ ps -f 24522
    UID        PID  PPID  C STIME TTY      STAT   TIME CMD
    <UID>    <PID><PPID>  0 11:16 pts/36   S      0:00 /bin/bash ./loop.sh
    $ jobs
    [1]+  Stopped                 ./loop.sh
    
    现在我们可以退出呼叫狂欢了。进程继续在后台运行。如果我们退出它的PPID变为1(init(1)进程),控制终端将变为未知

    $ ps -f <PID>
    UID        PID  PPID  C STIME TTY      STAT   TIME CMD
    <UID>    <PID>     1  0 11:16 ?        S      0:00 /bin/bash ./loop.sh
    $ /usr/bin/lsof -p <PID>
    ...
    loop.sh <PID> truey    0u   CHR 136,36                38 /dev/pts/36 (deleted)
    loop.sh <PID> truey    1u   REG   0,26     1127 15008411 /home/truey/loop.out
    loop.sh <PID> truey    2u   CHR 136,36                38 /dev/pts/36 (deleted)
    
    或者,可以使用以下一种衬里:

    gdb -q -ex 'call close(1)' -ex 'call open("loop.out", 01102, 0600)' -ex detach -ex quit -p <PID>
    
    gdb-q-ex'调用关闭(1)'-ex'调用打开(“loop.out”,011020600)'-ex分离-ex退出-p
    
    我希望这是对解决方案的一个相当完整的描述。

    $ ps -f 24522
    UID        PID  PPID  C STIME TTY      STAT   TIME CMD
    <UID>    <PID><PPID>  0 11:16 pts/36   S      0:00 /bin/bash ./loop.sh
    $ jobs
    [1]+  Stopped                 ./loop.sh
    
    $ bg %1
    [1]+ ./loop.sh &
    $ disown -h %1
    $ ps -f <PID>
    UID        PID  PPID  C STIME TTY      STAT   TIME CMD
    <UID>    <PID><PPID>  0 11:16 pts/36   S      0:00 /bin/bash ./loop.sh
    
    $ ps -f <PID>
    UID        PID  PPID  C STIME TTY      STAT   TIME CMD
    <UID>    <PID>     1  0 11:16 ?        S      0:00 /bin/bash ./loop.sh
    $ /usr/bin/lsof -p <PID>
    ...
    loop.sh <PID> truey    0u   CHR 136,36                38 /dev/pts/36 (deleted)
    loop.sh <PID> truey    1u   REG   0,26     1127 15008411 /home/truey/loop.out
    loop.sh <PID> truey    2u   CHR 136,36                38 /dev/pts/36 (deleted)
    
    call close(1)
    call open("loop.out", 01102, 0600)
    # call close(2)
    # call open("loop.err", 01102, 0600)
    detach
    quit
    
    gdb -q -ex 'call close(1)' -ex 'call open("loop.out", 01102, 0600)' -ex detach -ex quit -p <PID>