Python:子进程循环无限循环

0 投票
2 回答
1105 浏览
提问于 2025-04-15 18:39

我想通过一个Python脚本来启动和停止 rsyslog 服务:

RSYSLOG_INIT_SCRIPT='/etc/init.s/rsyslogd'
subprocess.call([RSYSLOG_INIT_SCRIPT,'stop'])

/etc/init.d/rsyslogd 是一个普通的初始化脚本。问题是它会不断重复执行这个脚本。(我在脚本中加了一个输出语句来确认这一点)。

当我终止它时,出现了以下的错误追踪信息:

  File "queuerunner.py", line 72, in <module>
    rsysloglauncher.startrsyslog()
  File "/root/logging-server/Logging-server-init/src/initializer/rsyslog/rsysloglauncher.py", line 23, in startrsyslog
    subprocess.call([RSYSLOG_INIT_SCRIPT,"stop"])
  File "/storage/local/python-2.6.4/lib/python2.6/subprocess.py", line 470, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/storage/local/python-2.6.4/lib/python2.6/subprocess.py", line 1157, in wait
    pid, sts = os.waitpid(self.pid, 0)

2 个回答

0

你确定这个脚本没有自己循环吗?这个Python代码看起来只是一直在等子进程结束。

先获取这个Python脚本的进程ID,然后执行:

watch pstree -ap <PID>

检查一下启动/停止脚本的进程ID是否相同——可能是Python代码因为某种原因在自己循环。

如果init.d脚本的进程ID是固定的,那就对这个进程ID使用stracetruss命令,看看它在干什么。

1

不太确定发生了什么,但你可以试着这样创建你的脚本:

#!/bin/sh
while :
do
    echo "Sleeping..."
    sleep 1
done

然后确认一下,当你的 Python 程序运行这个脚本时,是否能得到相同的结果。

接着,用这个脚本确认一下 Python 的调用:

#!/bin/sh
echo "I will exit"

看看能否从原始脚本中获取更多的输出,创建一个“代理”脚本——你会从你的 Python 脚本中调用这个代理脚本。

#!/bin/sh
/etc/init.s/rsyslogd stop > /tmp/log 2>&1

并且修改你的原始脚本,让它输出更多的信息:

#!/bin/sh -xv

我假设你用的是 bourne-shell 或 bash。

然后调用这个脚本,接着检查一下 /tmp/log 里的内容:

tail -f /tmp/log

另外,你能否获取到:

subprocess.call(...

返回创建的进程的 PID?如果可以的话,可以用类似这样的方式来跟踪它:

ps -eaf |grep <PID>

其中应该用实际的 PID 来替换。

根据操作系统的不同,你可能还可以:

truss -o /tmp/truss.out <PID>

如果这个 'truss.out' 文件不断填充系统调用的信息,那就说明你的脚本在循环运行——这时命令行调用和 Python 调用之间肯定有些不同(我还不太确定是什么)。

我同意其他人的看法:看起来这个脚本在循环运行——而不是 Python 脚本本身有问题。

还有一个可以尝试的办法:

在脚本开始的地方,输出一下参数——如果它无法获取到正确的参数,可能就会导致循环。

撰写回答