Python + Ubuntu Linux + nohup 错误:[1]+ Exit

14

我有一个Python脚本practice_one.py,我希望它在Ubuntu Linux中永远运行,并具有以下功能:

while True:
   #    Code

我尝试运行nohup python practice_one.py &,但得到了消息:nohup: ignoring input and appending output to ‘nohup.out’

然后当我按下回车键时,输出另一条消息:[1]+ Exit nohup python practice_one.py

为什么它会自动退出?我做错了什么吗?

编辑

尝试过以下命令:nohup python practice_one.py </dev/null &>/dev/null &

并得到[1] 61122,然后我按回车键,得到了[1]+ Exit nohup python practice_one.py </dev/null &>/dev/null &的消息。

以前可以工作,现在却退出了...现在可能是什么问题呢?


1
请查看 nohup.out 文件以获取任何错误信息。 - Klaus D.
你在那个循环体中没有任何代码,对吧? - moooeeeep
我会通过在脚本中添加Python shebang(例如“#!/usr/bin/env python”)来开始解决此问题。接下来,我会运行以下bash命令,以确保所有用户都可以执行该脚本:chmod +x practice_one.py。然后,在shebang之后但在任何其他内容之前,我会将一个简单的写入外部文件添加到脚本中,例如with open("my_file.txt", "w") as file: file.write("OK"),然后再次尝试运行该文件,并查看外部文件是否已打印出“ok”。如果您尝试了这些步骤,请在此线程中回复结果,以便我可以进一步帮助。 - Jamil Said
你能把你的脚本发布到某个地方吗?也许可以学到一些新东西。 - Chibueze Opata
如果“以前可以工作,但现在退出了..”,那么问题不可能出在驱动程序上。每个人都经历过这种情况 :-) - Dinesh
8个回答

9

我通常在以下三种情况下遇到这个问题:

  1. 在while循环中发生异常时。

  2. 在代码的某个地方使用了pdb.set_trace(),这是一个调试断点。

  3. 在代码的某个地方,需要用户输入,例如raw_input("Please enter something: ")

检查你的代码,排除这三种原因。

不要担心第一条消息,只是告诉你nohup正在工作。

编辑

  1. 在使用nohup运行脚本之前,请确保脚本本身可以正常工作(这实际上应该是尝试的第一件事)。

这是“答案”,因为问题缺乏足够的细节来表明其他情况。我打赌是第四个选项.... :) - Jesse Adelman

5

我建议您最好使用双重fork魔术来运行长时间运行的程序作为守护进程,而不是使用nohup。这样易于调试,您的程序也不需要像nohup那样的外部工具。

daemon.py

import sys
import os

# double fork magic
def daemonize():
    os.umask(0)

    try:
        pid = os.fork()
    except OSError:
        sys.exit(0)
    if pid > 0:
        sys.exit(0)
    os.setsid()

    try:
        pid = os.fork()
    except OSError:
        sys.exit(0)
    if pid > 0:
        os._exit(0)

    os.chdir('/')

    import resource     # Resource usage information.
    maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
    if (maxfd == resource.RLIM_INFINITY):
        maxfd = 1024

    # Iterate through and close all file descriptors.
    for fd in range(0, maxfd):
        try:
            os.close(fd)
        except OSError:   # ERROR, fd wasn't open to begin with (ignored)
            pass

    fd = os.open(os.devnull, os.O_RDWR)
    os.dup2(fd, sys.stdin.fileno())
    os.dup2(fd, sys.stdout.fileno())
    os.dup2(fd, sys.stderr.fileno())

test.py

from daemon import daemonize
import time


def test():
    while True:
        time.sleep(10)

if __name__ == '__main__':
    daemonize() # you could comment this line before you make sure your program run as you expect
    test()

现在,使用 python test.py 命令将其作为守护进程运行,并且可以使用 ps aux | grep test.py 命令进行检查。

3

我同意Ash的看法,你在脚本中遇到了一些问题。

我已经测试了你的场景并向你保证:nohup不是问题

Python代码

$ cat practice_one.py
while True:
   print 'ok'

Nohup执行

m.ortiz.montealegre@CPX-XYR3G1DTHBU ~/python_excercises/nohup-python
$ nohup python practice_one.py &
[1] 10552

m.ortiz.montealegre@CPX-XYR3G1DTHBU ~/python_excercises/nohup-python
$ nohup: ignoring input and appending output to 'nohup.out'

m.ortiz.montealegre@CPX-XYR3G1DTHBU ~/python_excercises/nohup-python
$ ps
      PID    PPID    PGID     WINPID   TTY         UID    STIME COMMAND
    10552   15248   10552       9992  cons1    6758389 16:52:27 /usr/bin/python2.7

因此,请尝试简化您的脚本操作,通过注释代码并测试,找出问题所在。

2

在脚本上设置执行权限

chmod +x practice_one.py

尝试关闭所有文件描述符。

nohup ./practice_one.py <&- 1>&-  2>&- &

1
在代码中,应该加入中断。我的意思是; 即使你不会到达它,你也应该有一个退出状态。在退出状态下,您可以指定使while循环变为真。建议使用for循环代替。
来源: https://wiki.python.org/moin/WhileLoop

1
第一个并不是错误 - 它只是意味着 nohup 会捕获 STDOUT 并将其存储在 nohup.out 中。如果您想要静音,请使用:
nohup python practice_one.py &>/dev/null

所有东西都被静音了,但我该如何检查它是否实际运行? - Jo Ko
嗯,ps aux | grep python - zwer
为什么像4EAST这样的字符串会被识别为4%EF%BF%EF%BF%BD等等? - Jo Ko
这取决于文本和 shell 编码、终端表示等因素,而且超出了你最初的问题范围。 - zwer
当我运行命令查看是否正在运行nohup时,列表上应该显示什么?我不认为我看到任何nohup。 - Jo Ko
上述命令将显示包含Python名称的进程列表。其中一个应该以类似于/usr/bin/python practice_one.py的内容结尾(不会提到nohup)。这是如果您的脚本在此期间没有退出(由于我们在上面静音输出,因此无法知道原因)。 - zwer

0

我刚遇到了这个问题。我很确定你的代码有问题,否则就不会出现退出消息。


-1

这是 nohup 的正常行为。 为了避免这种情况,请尝试:

nohup python my_script.py </dev/null &>/dev/null &

不要解决问题...(脚本退出的事实) - Riccardo Petraglia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接