首页 > 解决方案 > subprocess.communicate() 不会向通过 git 调用 ssh 的 Popen 提供输入

问题描述

我正在使用 python 2.7,所以我无法使用我认为可行的方法(带有输入参数的 subprocess.check_ouput()),我试图将字符串“yes”传递给 Popen 对象。这是我的代码。

def clone(ssh_url):
    sub_list = ['git', 'clone', ssh_url]
    cmd = subprocess.Popen(sub_list, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                           universal_newlines=True)
    output, err = cmd.communicate(input='yes')
        print output
        if err is not None:
            print err

ssh_url = 'git@gitlab.com:User1/test-work.git'
clone(ssh_url)

所以我正在尝试克隆一个 gitlab 项目。我之前没有在这台机器上使用过 ssh 密钥,所以我收到一条消息,说明 ECDSA 密钥指纹的值是什么以及我是否要继续连接(是/否)。我想在显示时将“是”传递给此选择,但是,我提供的输入communicate()未收到,并且我Host Key verification failed. fatal: Could not read from remote repository从 git 收到错误。

有谁知道使这项工作的方法?通信()是否阻塞?我在这里尝试使用线程示例,使用 subprocess.communicate() 来管道 stdin 而无需等待 process,在接受的响应中,但这也不起作用。

标签: pythongitsubprocess

解决方案


这是 SSH 有意的、期望的行为。这并不是您在 Python 中做错了什么——相反,SSH 故意不使用标准输入来收集与安全相关的提示的答案(这确保其标准输入被传递给远程命令,而不是由 SSH 本身使用)。

git_env = os.environ.copy()
git_env['GIT_SSH_COMMAND'] = 'ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
cmd = subprocess.Popen(sub_list,
  stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
  universal_newlines=True, env=git_env)

推荐阅读