【问题标题】:Running a nohup command through SSH with Python's Popen then logging out使用 Python 的 Popen 通过 SSH 运行 nohup 命令,然后注销
【发布时间】:2017-07-19 07:55:44
【问题描述】:

我正在尝试使用此answer 使用subprocess.Popen 使用nohup 发出一个长时间运行的进程,然后退出连接。

如果我从登录 shell 运行

$ nohup sleep 20 &
$ exit

我得到了预期的行为,即我可以在睡眠过程仍在运行时注销,稍后再连接以检查其状态。但是,如果我通过 Python 尝试相同的操作,似乎 exit 命令在睡眠时间结束之前不会被执行。

import subprocess

HOST=<host>
sshProcess = subprocess.Popen(['ssh', HOST],
                                stdin = subprocess.PIPE,
                                stdout = subprocess.PIPE,
                                universal_newlines = True,
                                bufsize = 0)
sshProcess.stdin.write("nohup sleep 20 &\n")
sshProcess.stdin.write("exit\n")
sshProcess.stdin.close()

我错过了什么?

【问题讨论】:

  • 为什么不只是subprocess.Popen(['ssh', HOST, 'nohup', 'sleep', '20'], stdin = subprocess.PIPE, stdout = subprocess.PIPE)
  • 因为我的 Python 进程会一直运行直到睡眠完成,而我想发出命令(这将是一个长时间运行的 Python 进程)然后退出并做其他事情。
  • 您可以从Popen 中删除管道以在后台运行。更多信息在这里stackoverflow.com/a/7224186/524743

标签: python ssh subprocess nohup


【解决方案1】:

来自文档:Python Docs

警告使用communicate() 而不是.stdin.write、.stdout.read 或.stderr.read 以避免由于任何其他操作系统管道缓冲区填满并阻塞子进程而导致的死锁。

好吧,我现在明白了:

关于communicate():[...]等待进程终止 所以我猜你之前的解决方案更好。但是如果你在最后调用它 if 不应该是一个问题,或者如果你不需要 stdin 或 stderr 作为输出就根本不调用它

但是根据这个:StackOverflow Comment 如果您在 Popen 调用中设置 preexec_fn=os.setpgrp 它应该可以工作。

【讨论】:

  • 我试过communicate(),但我得到了同样的行为。在我可以运行其他任何东西之前,我仍然需要等待睡眠过程完成。
  • 确实,(对我来说)神秘的preexec_fn=os.setpgrp 可以解决问题。感谢您指出这一点。
猜你喜欢
  • 2014-05-04
  • 2014-06-03
  • 2015-10-09
  • 2010-10-08
  • 2011-01-25
  • 2022-08-23
  • 1970-01-01
  • 1970-01-01
  • 2014-04-07
相关资源
最近更新 更多