1

我正在将 Git 支持添加到用 Python(使用 PyQt)编写的现有应用程序中。我决定通过subprocess.Popen和解析不同命令的结果直接与 Git 命令交互(因为对于我们想要实现的几件事,导入一个完整的第三方库似乎并不合适)。

到目前为止,我已经成功地合并了git branchand git remote,这或多或少是有效的,因为我仍然在我的本地仓库中。
现在我正在解决git fetch并遇到困难。

首先,我从标准错误上的 gnome-keyring 得到一个“警告”。这是由于我的安装有问题,但我们当然不应该因为这样的事情而挂断电话。所以我只是忽略了这个警告。可能这很老套,但现在我认为如果应该报告问题,我们可以忍受添加这样的变通方法。

但是后来我遇到了 shell 要求我(再次在 stderr 上)输入我的 SSH 密码的问题。这也是我在特定计算机上安装的问题,但如果用户更喜欢亲自输入密码,我们应该接受。所以我必须处理这种情况。


因此,在冗长的介绍之后,问题相当简洁:

如果我git fetch通过 Python运行一个 shell 命令,subprocess.Popen并且这个 shell 程序要求用户反馈,我如何从 Python 与它进行交互?
基本上我想向用户显示标准错误输出并允许他输入密码。(然后当然实现一个选项来将此密码存储在应用程序中。)

4

2 回答 2

0

如果我没记错的话,ssh 对它与用户的交互方式非常讲究,甚至直接打开/dev/tty(而不仅仅是尝试使用它STDERR_FILENO)。但是,您可以设置SSH_ASKPASSDISPLAY使其使用 X11 显示器上的特定程序。手册页指出,您可能必须将其标准输入连接/dev/null到才能完成这项工作。

因此,这两种选择似乎是使用它,或者从 Python 中分配一个伪 tty,并运行需要 ssh 的 git 命令,并将该 pty 作为其控制终端。内置的(但仅适用于 Unix/Linux)os.openpty将使您在其中取得成功,但还有更多工作要做。

pexpect 模块中包含您需要的所有内容,尽管我自己从未使用过它。

于 2013-10-10T18:46:15.910 回答
0

这取决于您正在构建的确切内容,但在我的情况下,可以通过编程方式检测到这一点,然后要求用户运行以下命令并重新启动程序:

eval $(ssh-agent -s)
ssh-add

一旦他们这样做,错误就会消失。我的电话git fetch看起来像这样:

p = Popen(['git', 'fetch'], cwd=repo_dir, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()

在接下来的几行中,检查是否p.returncode为 128。这似乎是发生这种情况时返回的数字,如此所述。

让 python 提示输入 ssh 密码会很好,但让它工作听起来有点痛苦,尤其是在没有外部库的情况下。

于 2019-02-27T13:20:19.167 回答