python:使用Popen与shell命令交互

python:使用Popen与shell命令交互,python,stdin,popen,Python,Stdin,Popen,我需要使用python执行几个shell命令,但我无法解决其中一个问题。当我将scp添加到另一台机器时,通常会提示并询问是否将此机器添加到已知主机。我希望程序自动输入“是”,但我无法让它工作。到目前为止,我的程序如下所示: from subprocess import Popen, PIPE, STDOUT def auto(): user = "abc" inst_dns = "example.com" private_key = "sample.sem" capFi

我需要使用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

如果我运行这个程序,它仍然会提示并请求输入。如何自动响应提示?谢谢。

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

严格的密钥检查

如果此标志设置为“是”,ssh(1)将永远不会自动向~/.ssh/known_主机添加主机密钥 文件,并拒绝连接到主机密钥已更改的主机。这提供了最大的保护 针对特洛伊木马攻击,尽管当/etc/ssh/ssh\u known\u hosts文件 维护不善或经常连接到新主机时。此选项强制用户 手动添加所有新主机。如果此标志设置为“否”,ssh将自动添加新的主机密钥 到用户已知的主机文件。如果此标志设置为“ask”,则将向用户添加新的主机密钥 只有在用户确认这是他们真正想要做的事情之后才知道主机文件,ssh将

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

scp -o StrictHostKeyChecking=no ...
您还可以启用批处理模式:

批处理模式

如果设置为“是”,则将禁用密码短语/密码查询。此选项在脚本和脚本中非常有用 没有用户提供密码的其他批处理作业。参数必须为“是”或“是” “不”。默认值为“否”


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

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

严格的密钥检查

如果此标志设置为“是”,ssh(1)将永远不会自动向~/.ssh/known_主机添加主机密钥 文件,并拒绝连接到主机密钥已更改的主机。这提供了最大的保护 针对特洛伊木马攻击,尽管当/etc/ssh/ssh\u known\u hosts文件 维护不善或经常连接到新主机时。此选项强制用户 手动添加所有新主机。如果此标志设置为“否”,ssh将自动添加新的主机密钥 到用户已知的主机文件。如果此标志设置为“ask”,则将向用户添加新的主机密钥 只有在用户确认这是他们真正想要做的事情之后才知道主机文件,ssh将

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

scp -o StrictHostKeyChecking=no ...
您还可以启用批处理模式:

批处理模式

如果设置为“是”,则将禁用密码短语/密码查询。此选项在脚本和脚本中非常有用 没有用户提供密码的其他批处理作业。参数必须为“是”或“是” “不”。默认值为“否”


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

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


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

我知道的避免被问及指纹匹配的最佳方法是在
.ssh/known\u hosts
中预先填充相关密钥。在大多数情况下,您确实应该已经知道远程机器的公钥是什么,将它们放在ssh可以找到的
已知主机中是很简单的


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

标记
-q
是否有帮助
man
-q安静模式:禁用进度表以及来自ssh的警告和诊断消息(1)。
@LevLevitsky:嗯,不是真的,这只会发出警告,但我想,添加到已知主机是标准的提示。也许您最好使用ssh子进程,而不是ssh子进程。
-q
标志会有帮助吗
man
-q安静模式:禁用进度表以及来自ssh的警告和诊断消息(1)。
@LevLevitsky:嗯,不是真的,这只会发出警告,但我想添加到已知主机是标准提示。也许你最好使用ssh子进程,而不是ssh子进程。这是一个非常好的回答