我猜测你在运行Python 2代码。
如果是这种情况,subprocess.check_output()
不接受timeout
参数,并且该函数会立即失败,显示以下信息:
TypeError: __init__() got an unexpected keyword argument 'timeout'
然而,由于您捕获了所有异常并打印出一条通用消息,因此您看不到实际的异常,并且假定命令立即超时。
解决这个问题的一种方法是在Python 3中运行代码。
无论您使用Python 2还是3,我建议您不要捕获所有异常,或者至少打印异常的值,以便您可以查看实际的原因,例如:
try:
x=subprocess.check_output(command, shell=True, timeout=5)
except subprocess.TimeoutExpired as exc:
print("Command timed out: {}".format(exc))
exit()
else:
print (x)
这个方法明确检查超时异常。所有其他异常都像通常一样传播,因此不会被您的“捕获所有”代码掩盖。或者,
try:
x=subprocess.check_output(command, shell=True, timeout=5)
except Exception as exc:
print("Command failed: {}".format(exc))
exit()
else:
print (x)
但是更推荐前者。
编辑
如果您使用Linux,则可以使用timeout
命令,例如:
x = subprocess.check_output('timeout 5 {}'.format(command), shell=True)
当超时时,它会引发一个异常,并返回退出状态码为124:
subprocess.CalledProcessError: Command 'timeout 5 sleep 10' returned non-zero exit status 124
顺便提一下,你不应该使用shell=True
选项,因为在文档中提到它存在安全问题。相反,你应该像这样将一个字符串列表传递给check_output()
:
from shlex import shlex
command = shlex('timeout 5 {}'.format(command))
try:
x = subprocess.check_output(command)
except subprocess.CalledProcessError as exc:
if exc.returncode == 124:
print "Command timed out"
else:
raise
如果您使用的是其他操作系统(或者您不想使用 timeout
),那么您可以在单独的线程中运行子进程,并在必要时让主线程超时。请参阅另一个问题,如何使用'module subprocess'设置超时,了解如何实现。