python:使用Popen与shell命令交互

时间:2012-04-27 20:10:03

标签: python stdin popen

我需要使用python执行几个shell命令,但我无法解决其中一个问题。当我scp到另一台机器时,通常它会提示并询问是否将此机器添加到已知主机。我希望程序自动输入“是”,但我无法让它工作。到目前为止,我的程序看起来像这样:

from subprocess import Popen, PIPE, STDOUT

def auto():
  user = "abc"
  inst_dns = "example.com"    
  private_key = "sample.sem"
  capFile = "/home/ubuntu/*.cap"

  temp = "%s@%s:~" %(user, inst_dns)
  scp_cmd = ["scp", "-i", private_key, capFile, temp]

  print ( "The scp command is: %s" %" ".join(scp_cmd) )
  scpExec = Popen(scp_cmd, shell=False, stdin=PIPE, stdout=PIPE)
  # this is the place I tried to write "yes" 
  # but doesn't work
  scpExec.stdin.write("yes\n")
  scpExec.stdin.flush()
  while True:
    output = scpExec.stdout.readline()
    print ("output: %s" %output)
    if output == "": 
      break

如果我运行此程序,它仍会提示并要求输入。如何自动响应提示?感谢。

2 个答案:

答案 0 :(得分:4)

系统会提示您将主机密钥添加到知道主机文件,因为ssh已配置为StrictHostKeyChecking。从手册页:

  

StrictHostKeyChecking

     

如果此标志设置为“yes”,则ssh(1)永远不会自动将主机密钥添加到〜/ .ssh / known_hosts   文件,并拒绝连接到主机密钥已更改的主机。这提供了最大的保护   防止特洛伊木马攻击,虽然在/ etc / ssh / ssh_known_hosts文件中它可能很烦人   维护不善或经常与新主机建立连接。此选项强制用户   手动添加所有新主机。如果此标志设置为“no”,ssh将自动添加新的主机密钥   到用户已知的主机文件。如果此标志设置为“ask”,则会将新主机密钥添加到用户   只有在用户确认了他们真正想要做的事情之后才知道主机文件,而ssh将

如果您希望ssh / scp在没有提示的情况下自动接受新密钥,您可以将StrictHostKeyChecking设置为“no”。在命令行上:

scp -o StrictHostKeyChecking=no ...

您还可以启用批处理模式:

  

批处理模式

     

如果设置为“yes”,将禁用密码/密码查询。此选项在脚本和脚本中很有用   其他没有用户提供密码的批处理作业。论证必须是“是”或   “没有”。默认为“no”。

使用BatchMode=yes时,ssh / scp将失败而不是提示(这通常是对脚本的改进)。

答案 1 :(得分:1)

我知道避免被问及指纹匹配的最佳方法是预先填充.ssh/known_hosts中的相关密钥。在大多数情况下,您确实应该已经知道远程计算机的公钥是什么,并且可以直接将它们放在ssh可以找到的known_hosts中。

在您没有,也不能知道远程公钥的少数情况下,最正确的解决方案取决于您不知道的原因。例如,如果您正在编写需要在任意用户Box上运行的软件,并且可能需要代表用户ssh到其他任意框,那么您的软件最好自己运行ssh-keyscan获取表面上的远程公钥,让用户尽可能明确地批准或拒绝它,如果获得批准,则将密钥附加到known_hosts,然后调用ssh。