如何向 Python 子进程写入数据?

3

我想编写一个Python脚本,在执行文件后启动一个子进程来运行Azure CLI命令。

当我在本地运行时,我运行的是:

az pipelines create --name pipeline-from-cli --repository https://github.com/<org>/<project> --yml-path <path to pipeline>.yaml --folder-path _poc-area

我需要输入一个类似于此样式的提示信息:

Which service connection do you want to use to communicate with GitHub?
 [1] Create new GitHub service connection
 [2] <my connection name>
 [3] <org name>
Please enter a choice [Default choice(1)]:

我可以输入数字2并按回车键,然后我的Azure DevOps中成功创建流水线。我希望在提示时能够动态地输入并运行此命令。
到目前为止,我尝试过:
import subprocess

cmd = 'az pipelines create --name pipeline-from-cli --repository https://github.com/<org>/<project> --yml-path <path to pipeline>.yaml --folder-path _poc-area
cmd = cmd.split()

subprocess.run(cmd, shell=True)

这将以完全相同的方式运行,就像我在本地尝试运行时一样。
尝试遵循此处的答案:https://dev59.com/tWoy5IYBdhLWcg3wkOsK 我也尝试过:
p = subprocess.run(cmd, input="1", capture_output=True, text=True, shell=True)
print(p)

我执行时遇到了错误,报错信息为raise NoTTYException(error_msg)\nknack.prompting.NoTTYException

有没有办法让我执行这个 Python 脚本,它运行 Azure CLI 命令后自动输入 2 而无需手动干预?


那么,你对我给出的回答不感兴趣吗? - Orsiris de Jong
2个回答

0

在我看来,Daniel是正确的,你不应该在程序中处理stdin。 然而,如果你真的需要处理它,你应该使用pexpect包,它基本上打开一个进程,等待给定的输出,然后发送输入到进程的stdin。

这里是一个基本的例子:

import pexpect
from pexpect.popen_spawn import PopenSpawn

cmd = 'az pipelines create --name pipeline-from-cli --repository https://github.com/<org>/<project> --yml-path <path to pipeline>.yaml --folder-path _poc-area'
child = pexpect.popen_spawn.PopenSpawn('cmd', timeout=1)
child.expect ('.*Please enter a choice.*')
child.sendline ('2')
# child.interact()     # Give control of the child to the user.

请查看pexpect文档以获取更多详细信息。自v4.0以来,MS Windows支持已经可用。
另一个过时的解决方案是使用子进程,模拟基本上expect会做的事情:
import subprocess
from time import sleep

p = subprocess.Popen(azure_command, stdout=PIPE, stdin=PIPE, stderr=STDOUT)
sleep(.5)
stdout = p.communicate(input=b'2\n')[0]
print(stdout.decode())

不过,大多数CLI程序最好使用非交互模式。


抱歉回复晚了。由于我使用的是Windows机器,使用pexpect.spawn()命令会出现错误,提示AttributeError: module 'pexpect' has no attribute 'spawn'。当我使用替代方法时,会得到以下错误:File "C:\Python381\lib\subprocess.py", line 1307, in _execute_child hp, ht, pid, tid = _winapi.CreateProcess(executable, args, FileNotFoundError: [WinError 2] The system cannot find the file specified - agw2021
很遗憾赏金已经消失了。你安装的pexpect版本是什么?至于替代方案,根据你的命令,你需要添加shell=True以使PATHS变量存在。另外,为了保持理智,请尝试以UAC运行。 - Orsiris de Jong
刚刚更新了我的示例,使用cmd.exe作为命令,然后发送ipconfig进行测试。效果很好。 - Orsiris de Jong

0
你试图解决错误的问题。 az pipeline create 需要一个 --service-connection 参数。你不需要回答提示,可以在命令行中提供服务连接值并完全跳过提示。

当我添加--service-connection参数并使用与本地运行时提示相同的服务连接值时,会出现错误,指出“无法创建服务钩子订阅。存储库未引用服务连接。” - agw2021

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接