批处理脚本使用git和ssh键将变量传递给stdin

时间:2011-06-07 18:32:23

标签: git ssh batch-file batch-processing

我正在尝试编写一个批处理脚本来克隆一堆存储库。我的问题是用户有一个受密码保护的ssh密钥。因此,每次在批处理文件中运行call git clone blah@blah/blah.git时,都必须输入用户密码。我知道我可以从set \p userpwd=[Enter ssh pwd]获取密码,但如何将其传递给每次通话?

7 个答案:

答案 0 :(得分:3)

每次需要时避免为ssh密钥键入密码的最佳方法是使用ssh-agent。大多数Linux发行版都将ssh-agent作为用户会话的一部分启动。要开始使用ssh-agent运行ssh-add并输入密钥的密码短语一次。当您运行使用ssh的命令时,它将从ssh-agent获取解密密钥,而不是提示您输入密码。有些发行版甚至还有一个功能,它会将密码存储在密钥环中,并在登录时为您设置ssh-agent。

答案 1 :(得分:2)

这是一种实现相同效果的方法,但步骤与您在问题中暗示的步骤不同:

  1. 开始ssh-agent
  2. 使用ssh-add添加密钥(它只会询问密码一次)
  3. 根据需要启动尽可能多的git clone <url>
  4. 清理
  5. 第二步将要求输入密码,而不是使用set /p。以下批处理文件在某种程度上是github's ssh key guidelines的端口。我在Windows Vista的cmd.exe下用ssh连接到gitious,运行git 1.7.6.msysgit.0进行了测试。

    @rem Do not use "echo off" to not affect any child calls.
    @setlocal
    
    @:: Find out where is git installed
    @where git > __wheregit.txt
    
    @:: Under XP, there is no where command. Use this (thanks to Raymond Chen)
    @:: http://blogs.msdn.com/b/oldnewthing/archive/2005/01/20/357225.aspx
    @:: (for %%e in (%PATHEXT%) do @for %%i in (git%%e) do @if NOT "%%~$PATH:i"=="" echo %%~$PATH:i) > __wheregit.txt
    
    @:: Move it to a environment variable, we will need to manipulate the string
    @set /p wheregit= <__wheregit.txt
    @del __wheregit.txt
    
    @:: Parse the full file name of git.cmd to find the the path
    @for /F "delims=" %%I in ("%wheregit:~0,-7%..") do @set git_install_root=%%~fI
    @set PATH=%git_install_root%\bin;%git_install_root%\mingw\bin;%PATH%
    
    @:: The keys are in the home directory.
    @if not exist "%HOME%" @set HOME=%HOMEDRIVE%%HOMEPATH%
    @if not exist "%HOME%" @set HOME=%USERPROFILE%
    
    @ ::start ssh-agent, and save its output
    @ssh-agent > __ssh-agent.out
    
    @ ::parse the output and set environment vars needed by ssh-add
    @FOR /F "eol=; tokens=1* delims=;" %%i in ('findstr /v echo __ssh-agent.out') do @set %%i
    @del __ssh-agent.out
    
    @ ::add the key to the agent (this will ask for the password)
    @ssh-add %HOME%\.ssh\id_rsa
    
    @ ::Call git. When it's time to use the key, its password will be provided by ssh-agent
    @ ::Obviously you will put your git clone url here
    @call git clone git@gitorious.org:siaki-sso/siaki-sp.git
    @call git clone git@gitorious.org:siaki-sso/siaki-idp.git
    
    @ ::Kill ssh-agent
    @ssh-agent -k
    
    @endlocal
    

答案 2 :(得分:1)

正如其他人所说,使用ssh-agent是真正推荐的方式。

但是如果你真的想要弄脏脚本,并且密钥/密钥的密码是相同的,那么你可以使用特殊的SSH_ASKPASS环境变量。 这使您可以设置在SSH要提示输入密码时执行的“程序”。您可以随时将其指向磁盘上的某个脚本,该脚本只会吐出您在开始时从用户处获取的密码。

基本上取用户的密码,将其写入tmp文件,将其回显出来,将SSH_ASKPASS环境变量设置为该脚本,然后继续执行git / ssh操作。

有关相关主题,请参阅http://dovetail.com/forum/viewtopic.php?t=822http://git.661346.n2.nabble.com/SSH-ASKPASS-td2137400.html

答案 3 :(得分:0)

看看http://mah.everybody.org/docs/ssh。我们能够成功地将它用于Windows的Putty ssh客户端。

这将阻止提示用户输入密码。这比在通话中传递密码更好,imho。

答案 4 :(得分:0)

让我们看看我是否正确理解了这一点(我没有使用git,所以如果我离开这里请原谅我)你需要将pw传递给批处理文件命令吗? http://dos.rsvs.net/DOSPAGE/BATCHCOM.HTM#3
这是对.bat文件的输入管道的一个很好的解释,它应该允许你自动输入方向。

答案 5 :(得分:0)

ssh-agent很不错,但对于脚本我更喜欢OpenSSH的ControlMaster功能。

使用ControlMaster模式,您可以让脚本连接一次,让它在后台运行,然后使用其他ssh实例(包括scprsync,{{1} }等,重用现有的连接。这使得用户可以只键入一次密码(当设置控制主机时),即使执行了多个ssh命令。

git中搜索ControlMaster了解详情。

优于man ssh_config的优势:

  • 用户不必了解什么是ssh密钥或ssh-agent如何工作。
  • 用户不必生成ssh公钥/私钥对,如果脚本将由许多用户运行,这一点很重要。 (大多数人不了解ssh密钥,因此让一大群人生成它们是一种累人的做法。)
  • 用户无需将其公钥复制到远程服务器
  • 用户无需记住运行ssh-agent
  • 用户无需记住运行ssh-agent
  • 根据其配置方式,ssh-add可能会在脚本中途超出用户的键;这不会
  • 只启动了一个TCP会话,因此如果脚本反复连接(例如,一次复制一个小文件),速度会快得多。

缺点:

  • 编码更复杂。 My answer to a similar question包含一些示例UNIX shell代码。
  • 它只促进与同一服务器的其他连接(ssh-agent可用于连接到许多不同的服务器)
  • OpenSSH旨在用于类UNIX系统;我不知道ssh-agent功能是否适用于Windows

答案 6 :(得分:-1)

将其公钥添加到服务器上经过身份验证的hosts文件中。您根本不需要担心提示。 ---并使用没有密码短语的密钥。