如何在 Python 中以编程方式使用 Popen 提供命令输入 运行?

How to feed command inputs run with Popen programmatically in Python?

我创建了一个 Python 脚本,它执行多个 REST API 调用来获取一个 cookie,然后通过管道将 echo "my cookie value" 传递给 openconnect 应用程序使用密码openconnect command。目的是基本上连接到企业 VPN。

它以前工作得很好,只是现在要输入另一个输入,好像有 2 个网关服务器。其中之一需要手动选择并传递给提示。

考虑到 REST API 调用已经在获取需要传递给的 cookie,我故意只将 Python 执行对 openconnect 的调用的部分放在下面openconnect 提示:

# [...] lots of REST API calls to fetch the portal_userauthcookie:
# for the sake of simplicity let's say it has a dummy value
portal_userauthcookie = "blahblah"
print("portal-userauthcookie = \"{}\"".format(portal_userauthcookie))

# Call openconnect with the cookie / password we got above
cmd = "echo \"{}\"".format(portal_userauthcookie)
cmd += " |"
cmd += " openconnect"
cmd += " --protocol=gp"
cmd += " --usergroup portal:portal-userauthcookie"
cmd += " --user={}".format(username)
cmd += " {}".format(vpn_portal_url)

process = subprocess.Popen(cmd, shell=True, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr)
out, err = process.communicate()

脚本为运行时:

$ sudo ./bin/python3 ./main.py 
[sudo] password for perret:           
My username: my-username
My password: 
My non-expired smartphone app code: my-code
portal-userauthcookie = "blahblah"
POST another-corporate.url.com&clientVer=4100&clientos=Linux
Connected to [corporate-ip]:443
SSL negotiation with [corporate-url]
Connected to HTTPS on [corporate-url]
SAML login is required via POST to this URL:
<html>
<!-- corporate html -->
</html>

Enter login credentials
portal-userauthcookie: 
POST corporate.url.com
2 gateway servers available:
  gateway1 (blahblah-url-1)
  gateway2 (blahblah-url-2)
Please select GlobalProtect gateway.
GATEWAY: [gateway1|gateway2]:fgets (stdin): Resource temporarily unavailable

如何在 popen 命令的提示符下自动输入 gateway1

我试图添加另一个 echo 但似乎只有一个可以工作(我已经在传递用作密码的 cookie 的那个)。

您可以尝试使用 expect 工具来自动执行用户输入。只需检查 man expect 即可。它是使交互式命令行程序可编写脚本的成熟解决方案。

但是,根据 openconnect man page,可以通过 --cookie 选项而不是使用标准输入来指定 cookie。然后你可以尝试继续通过stdin发送网关。