Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python subprocess.call()未在超时时终止进程_Python_Subprocess - Fatal编程技术网

Python subprocess.call()未在超时时终止进程

Python subprocess.call()未在超时时终止进程,python,subprocess,Python,Subprocess,我不打算详细说明为什么需要这样做,但我的问题如下:我有一个字符串,其中包含一些需要运行的shell命令,其中可能包含一些输出重定向。考虑一个简单的例子: cmd=“yes>output.txt” 我希望能够通过python在超时的情况下运行这个命令,这样如果存在无限循环,该命令就不会永远运行。我正在使用子流程模块。这是我的密码: 导入子流程 subprocess.call(“yes>output.txt”,超时=1,shell=True) 当我运行这个程序时,我会在1秒后得到一个子进程.Ti

我不打算详细说明为什么需要这样做,但我的问题如下:我有一个字符串,其中包含一些需要运行的shell命令,其中可能包含一些输出重定向。考虑一个简单的例子:

cmd=“yes>output.txt”
我希望能够通过python在超时的情况下运行这个命令,这样如果存在无限循环,该命令就不会永远运行。我正在使用子流程模块。这是我的密码:

导入子流程
subprocess.call(“yes>output.txt”,超时=1,shell=True)
当我运行这个程序时,我会在1秒后得到一个
子进程.TimeoutExpired
异常,但进程没有终止。如果我查看
htop
,我仍然可以看到
yes
进程正在运行

奇怪的是,如果我通过解释器运行此命令,并在抛出异常后在提示下按下
Ctrl+C
,则会终止进程。我只是在做些傻事吗

我在macOS Catalina和Python3.7.7上以及Ubuntu18.04和Python3.6.9上都有这种行为

编辑:

如果我的命令将输出重定向到文件,我不确定为什么会出现不一致。例如:

subprocess.call(“睡眠100”,超时=1,shell=True)
会在进程超时时终止进程。但是,以下方面:

subprocess.call(“sleep 100>f”,超时=1,shell=True)
终止进程。我知道在这种情况下,实际上没有任何东西被重定向到该文件



更重要的是,我的实际问题是,在超时后的所有情况下,我将如何终止子进程?

timeout参数不是允许子进程的时间,而是允许父进程等待其子进程结束的时间。如果子项未在允许的时间内结束,则子项不会发生任何事情,父项将收到
TimeoutExpired
异常。所以你所观察到的是故意的

在交互式终端会话中键入Ctrl C时,SIGINT中断将发送到前台进程的进程组中的所有进程。由于您没有明确启动一个新的进程组,因此Python进程的子进程将共享同一个进程组并接收SIGINT。在这里,你所观察到的也是有意的

sleep
程序是特殊的。它在内部取决于SIGALARM中断,正如使用timeout参数调用子进程一样。这里,信号再次发送到整个进程组,因此子进程终止。但是我没有解释为什么将输出重定向到文件可以防止孩子被杀死

如果希望强制终止子级,则不应使用
调用
,而应明确创建和管理
进程
对象:

p = subprocess.Process("yes > output.txt", shell=True)
try:
    p.wait(timeout=1)
except subprocess.TimeoutExpired:
    p.terminate()

注意未测试的代码,因此可能会出现输入错误…

超时时间参数不是子进程允许的时间,而是父进程允许等待其子进程结束的时间。如果子项未在允许的时间内结束,则子项不会发生任何事情,父项将收到
TimeoutExpired
异常。所以你所观察到的是故意的

在交互式终端会话中键入Ctrl C时,SIGINT中断将发送到前台进程的进程组中的所有进程。由于您没有明确启动一个新的进程组,因此Python进程的子进程将共享同一个进程组并接收SIGINT。在这里,你所观察到的也是有意的

sleep
程序是特殊的。它在内部取决于SIGALARM中断,正如使用timeout参数调用子进程一样。这里,信号再次发送到整个进程组,因此子进程终止。但是我没有解释为什么将输出重定向到文件可以防止孩子被杀死

如果希望强制终止子级,则不应使用
调用
,而应明确创建和管理
进程
对象:

p = subprocess.Process("yes > output.txt", shell=True)
try:
    p.wait(timeout=1)
except subprocess.TimeoutExpired:
    p.terminate()

小心未经测试的代码,这样可能会出现打字错误…

如果它能帮助您解决问题,请查看此文档。看看这是否能帮到你。谢谢如果你能看一下的话,我已经更新了这个问题。更新后的解决方案似乎不起作用。在
p.terminate
之后,“是”进程仍在运行。知道为什么吗?PS:我想它是
子流程.Popen
,或者至少我用过。谢谢!如果你能看一下的话,我已经更新了这个问题。更新后的解决方案似乎不起作用。在
p.terminate
之后,“是”进程仍在运行。知道为什么吗?PS:我想它是
subprocess.Popen
,或者至少我用过它。