python - Python3 / subprocess.check_output / Timeout 不适用于每个命令
问题描述
我正在使用 Python 3.7.3 运行 Debian 10.8,并在脚本中运行一个子进程,我想在几秒钟后中断该子进程。这适用于 cmd_1 但不适用于以下示例中的 cmd_2 (永远不会触发超时):
import subprocess
import os, sys
# collect proxies and verify
try:
# cmd_1 = "while true; do sleep 1; done"
cmd_2 = "proxybroker find --types HTTPS -l 1000 --outfile proxybroker.txt"
timeout_sec = 3
subprocess.check_output(cmd_2, shell=True, timeout=timeout_sec)
except Exception as e:
print(e)
如果我在 bash 中运行 cmd_2,它工作正常。我确实使用pip3 install proxybroker
.
在另一个运行 Ubuntu 21.04 的系统上,超时适用于这两个命令。感谢有人可以提供提示。
解决方案
我无法准确解释为什么会发生这种情况,但摆脱无偿的外壳可以解决它。
tripleee@debian-buster-docker$ cat >subn.py
import subprocess
# import os, sys # unused import
# collect proxies and verify
try:
subprocess.check_output(['proxybroker', 'find', '--types', 'HTTPS', '-l', '1000', '--outfile', 'proxies.txt'], timeout=3)
except Exception as e:
print(e)
^D
tripleee@debian-buster-docker$ python3 subn.py
Command '['proxybroker', 'find', '--types', 'HTTPS', '-l', '1000', '--outfile', 'proxies.txt']' timed out after 3 seconds
我注意到当我用 KeyboardInterrupt 中断它时,您最初的尝试确实将超时消息打印为回溯的一部分。
tripleee@debian-buster-docker$ python3 sub.py
^CTraceback (most recent call last):
File "/usr/lib/python3.7/subprocess.py", line 474, in run
stdout, stderr = process.communicate(input, timeout=timeout)
File "/usr/lib/python3.7/subprocess.py", line 939, in communicate
stdout, stderr = self._communicate(input, endtime, timeout)
File "/usr/lib/python3.7/subprocess.py", line 1682, in _communicate
self._check_timeout(endtime, orig_timeout)
File "/usr/lib/python3.7/subprocess.py", line 982, in _check_timeout
raise TimeoutExpired(self.args, orig_timeout)
subprocess.TimeoutExpired: Command 'proxybroker find --types HTTPS -l 1000 --outfile proxybroker.txt' timed out after 3 seconds
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "sub.py", line 9, in <module>
subprocess.check_output(cmd_2, shell=True, timeout=timeout_sec)
File "/usr/lib/python3.7/subprocess.py", line 395, in check_output
**kwargs).stdout
File "/usr/lib/python3.7/subprocess.py", line 477, in run
stdout, stderr = process.communicate()
File "/usr/lib/python3.7/subprocess.py", line 939, in communicate
stdout, stderr = self._communicate(input, endtime, timeout)
File "/usr/lib/python3.7/subprocess.py", line 1681, in _communicate
ready = selector.select(timeout)
File "/usr/lib/python3.7/selectors.py", line 415, in select
fd_event_list = self._selector.poll(timeout)
KeyboardInterrupt
推荐阅读
- ios - 在 collectionView 单元格及其边框之间添加填充
- javascript - 如何仅使用 vanilla Javascript 从 Ajax 返回变量(字符串)
- python - 将列表制作成字典,由列表中的标签索引
- c# - 如何检查c#中是否包含数组?
- php - PHP 对象数组需要我克隆每个对象,否则它将持续更改
- jquery - Laravel 不会将数据从数据库填充到 Web 表单
- java - 检查 ArrayList 中是否存在 JTextfield 值
- android - 无法访问 zzbfm 类文件 zzbfm not found, firebase, android?
- c# - 序列化和读取对象列表的最佳方法?
- ios - 如何修复 iOS 中的滚动视图大小?