调用通过 ssh 创建子进程的 Python 脚本挂起

发布于 2024-12-07 08:51:41 字数 744 浏览 0 评论 0原文

我有一堆脚本,用于跨多个服务器启动类似的进程。我想将它们压缩为一个名为“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

I have a bunch of scripts that are used to start similar processes across a number of servers. I'd like to condense them down to one Python script called 'START', but something weird is happening when it's run over ssh.

$ ./START APP_A works as expected: APP_A is launched and begins doing its thing. Control is returned to the console immediately (before APP_A terminates).

$ ssh localhost /path_to/START APP_A sort of works: APP_A is launched and begins doing its thing, but ssh doesn't print any output to the screen or return control to the console until after APP_A terminates.

I assume it's a problem with signals or file handles, but I'm at a loss. Here's the Popen call that seems to be causing the trouble:

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

I'm using Python 2.4.3 on RHEL.

EDIT:
Wrapping the Python script seems to work:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夜夜流光相皎洁 2024-12-14 08:51:41

不要使用 shlex 与子进程结合调用。 它没有达到您的预期。相反,为子进程提供命令的 Python 列表,例如

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

Don't use shlex to call in conjunction with subprocess. It doesn't do what you expect. Instead, give subprocess a Python list of the command, like

subprocess.Popen(['/some/program', 'arg1', 'arg2', 'arg3'])
丑丑阿 2024-12-14 08:51:41

当你这样做时:

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

When you do:

ssh some_host remote_command remote_cmd_param

then it is normal that ssh does not return control before remote_command is done. If you want otherwise you need to sent it to background aby adding & at the end.

ssh redirects stdout of remote_command to its (local) stdout. If you don't see any output this may be because remote_command does not set any to stdout but tries to send it to the console for example. This is why you cannot do:

ssh remote_host mc # or any other command using terminal
猥︴琐丶欲为 2024-12-14 08:51:41

您应该将其放入 START_APP_A

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

然后它将起作用,并且 APP_A 的所有输出都将进入日志文件,您可以在需要时检查该日志文件。

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

You should put this in START_APP_A

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

Then it will work, and all the output from APP_A will go into a log file which you can inspect when you need to.

Note that if you need to inspect this output while APP_A runs, then you need to change APP_A so that it flushes stdout after printing or else change stdout to be unbuffered.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文