调用通过 ssh 创建子进程的 Python 脚本挂起
我有一堆脚本,用于跨多个服务器启动类似的进程。我想将它们压缩为一个名为“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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不要使用 shlex 与子进程结合调用。 它没有达到您的预期。相反,为子进程提供命令的 Python 列表,例如
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
当你这样做时:
那么在remote_command完成之前ssh不会返回控制权是正常的。如果您愿意,您需要通过在末尾添加
&
将其发送到后台。ssh 将remote_command 的标准输出重定向到其(本地)标准输出。如果您没有看到任何输出,这可能是因为 Remote_command 没有将任何内容设置为 stdout,而是尝试将其发送到控制台。这就是为什么你不能这样做:
When you do:
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:
您应该将其放入 START_APP_A
然后它将起作用,并且 APP_A 的所有输出都将进入日志文件,您可以在需要时检查该日志文件。
请注意,如果您需要在 APP_A 运行时检查此输出,则需要更改 APP_A 以便它在打印后刷新标准输出,或者将标准输出更改为无缓冲。
You should put this in START_APP_A
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.