我正在执行从python连接到外部服务器的程序 如果用户未通过身份验证,则程序会要求输入用户名和密码。
以下是子程序输出的外观:
Authentication Required
Enter authorization information for "Web API"
<username_prompt_here>
<password_prompt_here>
我想在打印'Authentication Required'后立即终止子进程,但问题是,我的代码工作错误 - 子进程要求提供凭据,用户提供后,子进程被终止。
这是我的代码:
with subprocess.Popen(self.command, stdout=subprocess.PIPE, shell=True, bufsize=1, universal_newlines=True) as process:
for line in process.stdout:
if 'Authentication Required' in line:
print('No authentication')
process.kill()
print(line)
我做错了什么?
答案 0 :(得分:1)
我做错了什么?
如果子进程及时刷新其stdout缓冲区,那么您的代码是正常的(如果您想在'Authentication Required'
行之后杀死子进程,无论其位置如何)。见Python: read streaming input from subprocess.communicate()
观察到的行为表明孩子使用了块缓冲模式,因此您的父脚本看到'Authentication Required'
行太晚或者使用process.kill()
杀死shell并不会杀死其后代(由命令创建的进程)。
解决方法:
--line-buffered
(由grep
接受),以强制执行行缓冲模式stdbuf
,unbuffer
,script
实用程序是否适合您的情况请参阅以下代码示例:
并且 - 并不总是我想在第一行之后杀死程序。仅当第一行是“需要身份验证”时才
假设修复了块缓冲问题,如果第一行包含Authentication Required
,则要终止子进程:
with Popen(shlex.split(command),
stdout=PIPE, bufsize=1, universal_newlines=True) as process:
first_line = next(process.stdout)
if 'Authentication Required' in first_line:
process.kill()
else: # whatever
print(first_line, end='')
for line in process.stdout:
print(line, end='')
如果您需要shell=True
,请参阅How to terminate a python subprocess launched with shell=True。