【问题标题】:Calling Python script that creates a subprocess over ssh hangs调用通过 ssh 创建子进程的 Python 脚本挂起
【发布时间】:2011-11-26 04:09:27
【问题描述】:

我有一堆脚本用于跨多个服务器启动类似的进程。我想将它们浓缩为一个名为“START”的 Python 脚本,但是当它通过 ssh 运行时会发生一些奇怪的事情。

$ ./START APP_A 按预期工作:APP_A 已启动并开始执行其操作。控制立即返回到控制台(在 APP_A 终止之前)。

$ ssh localhost /path_to/START APP_A 类似的工作:APP_A 已启动并开始执行其操作,但 ssh 不会将任何输出打印到屏幕或将控制权返回到控制台,直到 APP_A 终止。

我认为这是信号或文件句柄的问题,但我不知所措。这是似乎造成问题的 Popen 调用:

sub = subprocess.Popen(shlex.split(cmd), stdout=open(file_out, 'a+'), stderr=subprocess.STDOUT, close_fds=True)
print 'New PID:', sub.pid

我在 RHEL 上使用 Python 2.4.3。

编辑: 包装 Python 脚本似乎可行:

DIR="$( cd "$( dirname "$0" )" && pwd )"
pushd $DIR >> /dev/null
./START $1 &
popd >> /dev/null

【问题讨论】:

    标签: python ssh subprocess


    【解决方案1】:

    不要使用 shlex 与子进程一起调用。 It doesn't do what you expect。相反,给 subprocess 命令的 Python 列表,比如

    subprocess.Popen(['/some/program', 'arg1', 'arg2', 'arg3'])
    

    【讨论】:

    • 从 ssh 启动脚本与直接调用它会如何受此影响?该脚本在直接调用时工作正常。
    【解决方案2】:

    当你这样做时:

    ssh some_host remote_command remote_cmd_param
    

    那么在 remote_command 完成之前 ssh 没有返回控制权是正常的。如果需要,您需要通过在末尾添加& 将其发送到后台。

    ssh 将 remote_command 的标准输出重定向到它的(本地)标准输出。如果您没有看到任何输出,这可能是因为 remote_command 没有将任何内容设置为 stdout,而是尝试将其发送到控制台。这就是你不能这样做的原因:

    ssh remote_host mc # or any other command using terminal
    

    【讨论】:

    • START 脚本会输出一些调试信息,这些信息会使用 print 打印到 STDOUT。当我直接调用脚本时,程序会显示此信息并退出。当我通过 ssh 调用脚本时,它只会在子进程终止后打印信息。子进程本身将其他数据记录到自己的标准输出(在 Popen 调用中明确设置)。
    【解决方案3】:

    你应该把它放在 START_APP_A

    nohup /path/to/APP_A >/path/to/log 2>&1 </dev/null &
    

    然后它就会工作,APP_A 的所有输出都将进入一个日志文件,您可以在需要时对其进行检查。

    请注意,如果您需要在 APP_A 运行时检查此输出,则需要更改 APP_A 以便它在打印后刷新标准输出,或者将标准输出更改为无缓冲。

    【讨论】:

    • “stdout=open(file_out, 'a+'), stderr=subprocess.STDOUT” 是否已经重定向了 IO?
    • 也许是这样,也许不是。当你用 shell 脚本包装它时,它可以工作,所以为什么不直接使用 shell。此外,我不清楚您在本地运行哪些位以及远程运行哪些位。您错过的一件事是标准输入,它可能重要也可能不重要。在任何情况下,一行 shell 脚本都可以与任何语言的任何应用程序一起使用,以便在您使用 ssh 连接到的远程服务器上运行它。阅读 nohup 的手册页以了解更多信息。
    猜你喜欢
    • 2012-06-04
    • 2016-12-02
    • 1970-01-01
    • 1970-01-01
    • 2013-08-18
    • 1970-01-01
    • 2014-01-14
    • 1970-01-01
    • 2012-10-14
    相关资源
    最近更新 更多