【问题标题】:python subprocess output on nohupnohup 上的 python 子进程输出
【发布时间】:2014-03-15 06:41:07
【问题描述】:

尝试使用 python 脚本监控远程机器的可用物理磁盘空间,该脚本使用 subprocess.popen 执行df -h . 命令。

import subprocess
import time
command = 'ssh remoteserver "df -h ."'
while True:
    proc = subprocess.Popen(command,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    output,err=proc.communicate()
    print output
    print err
    time.sleep(60)

脚本运行良好,从命令行运行时将输出打印到终端

$> python2.7 script.py

Filesystem            Size  Used Avail Use% Mounted on
remoteserver:/home/user
                      555G  447G  109G  81% /home

当使用 nohup 命令启动脚本时,脚本不产生任何输出或似乎被阻塞。

$> nohup python2.7 script.py &

希望脚本在nohup 启动时使用上述脚本运行并获取远程机器的磁盘空间。

【问题讨论】:

  • 为什么不使用 bash 脚本?这样的任务不是更好吗?
  • 上面的代码是脚本的一部分,它做的其他事情很少,必须在 python 中完成。
  • nohup 可能会将输出重定向到文件 (nohup.out)

标签: python subprocess output nohup


【解决方案1】:

我不是 100% 确定这里的潜在问题,但是当您在 shell 中调用 NOHUP 时,它会断开一些 STDIN/STDOUT 与终端进程的连接,我怀疑这会导致您正在处理的一些交互看到。

鉴于您是从远程计算机上执行此操作的,我实际上建议您考虑使用类似 Fabric 的库来完成您所追求的工作。它非常简单,可以完成大部分终端会话的处理,并在您完成后很好地为您关闭。

类似:

from fabric import api
from fabric.api import env
import fabric

env.host_string = '%s@%s' % (username, remote_host)
env.disable_known_hosts = True
env.password = password
fabric.state.output['stdout'] = False
fabric.state.output['stderr'] = False

results = api.run('df -h')

【讨论】:

    【解决方案2】:

    您可以尝试将 stdin=subprocess.PIPE 发送到 subprocess 命令,然后在 call() 之前在下一行调用 proc.stdin.close()。或者您可以尝试将命令更改为 'ssh remoteserver "df -h"。 /null'。其他人报告使用 FNULL = open(os.devnull, 'r') 并将 FNULL 传递给 stdin= 参数,但我不确定您是否需要在之后调用 FNULL.close()。

    SSH 从 nohup 运行时很可能出于某种原因等待输入。可能是在nohup环境下无法认证,要求输入密码?

    为确保 SSH 不等待输入,请尝试在 ssh 命令中添加 -o "BatchMode yes" 并查看子进程通信调用的输出/错误中是否有一些线索。

    【讨论】:

      猜你喜欢
      • 2012-05-11
      • 2018-01-29
      • 2011-04-05
      • 1970-01-01
      • 2011-08-29
      • 2018-10-04
      • 2011-09-08
      • 2018-05-28
      • 2019-05-19
      相关资源
      最近更新 更多