Cygwin/Git 奇怪的终端问题

Cygwin/Git 奇怪的终端问题

好吧,这很奇怪。首先,这是在最新的 cygwin 上运行的 mintty,git 是从 cygwin 的 setup.exe 中提取的。我正在运行 zsh。

$ git clone https://<user>@<domain>/<repository>/ ~/src/project/dev
Initialized empty Git repository in /cygdrive/c/src/project/dev/.git/
Password: <actual password in plain text appears>
# Nothing happens...
^C
$ <password text that I just typed>
zsh: command not found: <same password text>

这是怎么回事?这是终端问题、shell 问题、git 问题还是 cygwin 问题?

更新:是的,我运行的是 Cygwin git 版本,而不是 Windows 版本:

$ which git
/usr/bin/git
$ git --version
git version 1.7.1
$ /cygdrive/c/Program\ Files\ \(x86\)/Git/bin/git.exe --version
git version 1.7.0.2.msysgit.0

答案1

好的,我想我找到了一个明确的解决方案。

问题是,无论使用什么终端(puttycyg、mintty、cmd.exe),默认情况下,在没有更好的配置替代方案的情况下,Git 会尝试使用“简单密码提示”(正如您在core.askpass 配置选项)。

简单的密码提示显然只在真正的 UNIX 上有效,但在 Cygwin 上无效。

解决方案是安装一个与 Windows 兼容 SSH_ASKPASS 的程序并配置 Git 来使用它。

我所做的是:

  1. 安装win-ssh-askpass应用程序解压并复制到 C:\
  2. 下载并安装 win-ssh-askpass 所需的 Borland Delphi 5 运行时(现在很难找到,但在http://www.satsignal.eu/software/runtime.html
  3. 配置 Git 使用 win-ssh-askpass: 获取密码git config --global core.askpass "C:/win_ssh_askpass.exe"。请注意,EXE 文件的名称中有下划线,而不是减号。
  4. 记得总是将您的登录名放在 URL 中 ( https://<user>@<domain>/<repository>)。否则,Git 会先询问登录名,然后再询问密码,使用相同的 askpass 实用程序。您可能会在不知情的情况下输入密码作为登录名,该密码将发送到 Web 服务器并以纯文本形式记录在其访问日志中!

现在 Git 使用优雅的 GUI 窗口询问密码,并且无论使用哪个终端都可以工作:)

答案2

我遇到过同样的问题 - 但是就我而言,我在 Cygwin 服务器中使用 SSH,因此 Win32 GUI askpass 显然不起作用。

相反,我编写了这个简单的脚本来执行 askpass。我以为它也可以通过从中获取 tty 设备从常规提示符中使用,/bin/tty.exe但由于未知原因,这不起作用(您可以自行使用 tty 或寻找其他解决方案来获取 tty,也许我只是弄错了)。

/bin/askpass.sh:

#!/bin/bash

TTY=$SSH_TTY
[ -c "$TTY" -a -r "$TTY" -a -w "$TTY" ] \
  || { echo "Failed to open device \`$TTY'!"; exit 1; }
exec <$TTY

echo -n "$@" >$TTY
read -s P
echo >$TTY

echo $P

确保此脚本可执行,并将其用作 git 的 core.askpass 设置。由于此脚本依赖于 $SSH_TTY 变量,因此通常只能通过 SSH 工作。但是,您可以设置 $SSH_TTY.bashrc.bash_profile取消设置;这样它甚至可以从控制台工作。rc 脚本中的以下行应该可以做到这一点:

[ -z "$SSH_TTY" ] && export SSH_TTY=$(/bin/tty.exe)

答案3

URL 中可能包含元字符,例如&。这会导致 git 在后台运行,在 Unix 系统上,它会在尝试从 stdin 读取时立即停止。A;还会在行中途终止命令,而Ctrl-C会导致行的其余部分(单独的命令)中止。

有趣的是,即使您告诉它使用,git它也会初始化 repo (除非您的主目录位于陌生的地方)。这表明该命令没有看到命令行的其余部分,如果URL 中有一个流浪的或,就会发生这种情况。/cygdrive/c/src/project/dev/.git/~/src/project/devgit&;

(我在使用 时曾多次遇到过这个问题wget,尽管没有遇到过git。)

尝试git clone使用不同的存储库,或使用同一存储库中的不同传输方式,以查看是否git总体上有问题,还是只针对此存储库有问题。您还可以尝试在 URL 周围加上单引号。

答案4

上述解决方案对我来说不起作用,但我找到了另一个。

你必须运行 ssh 代理

只需添加到 ~/.bashrc 并重新启动控制台

SSH_ENV=$HOME/.ssh/environment



# start the ssh-agent

function start_agent {

    echo "Initializing new SSH agent..."

    # spawn ssh-agent

    /usr/bin/ssh-agent | sed 's/^echo/#echo/' > "${SSH_ENV}"

    echo succeeded

    chmod 600 "${SSH_ENV}"

    . "${SSH_ENV}" > /dev/null

    /usr/bin/ssh-add

}



if [ -f "${SSH_ENV}" ]; then

     . "${SSH_ENV}" > /dev/null

     ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {

        start_agent;

    }

else

    start_agent;

fi

PS Chrome 和 Opera 使用与 bash 不兼容的换行符 - 只需使用其他浏览器进行复制粘贴即可

相关内容