Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Python避免SSH密码提示';s子进程库_Python_Linux_Ssh_Subprocess - Fatal编程技术网

使用Python避免SSH密码提示';s子进程库

使用Python避免SSH密码提示';s子进程库,python,linux,ssh,subprocess,Python,Linux,Ssh,Subprocess,我正在构建一个程序,该程序通过尽可能少的用户干预将命令发送到多个服务器。 对于这个程序,我使用子进程通过SSH发送命令 交互的服务器是多个且动态的。 该计划将主要由我公司的团队成员使用。 大多数服务器在/root/.ssh/authorized_keys处都有正确的文件,程序可以很好地使用它们 但是有些服务器安装得不好,我们无法在不输入root密码的情况下使用SSH连接它们。 SSH密码提示挂起,此时它需要SSH.stdout.readlines()“有问题的服务器” 我如何确保程序在每次面对由

我正在构建一个程序,该程序通过尽可能少的用户干预将命令发送到多个服务器。 对于这个程序,我使用子进程通过SSH发送命令

交互的服务器是多个且动态的。 该计划将主要由我公司的团队成员使用。 大多数服务器在/root/.ssh/authorized_keys处都有正确的文件,程序可以很好地使用它们

但是有些服务器安装得不好,我们无法在不输入root密码的情况下使用SSH连接它们。 SSH密码提示挂起,此时它需要
SSH.stdout.readlines()
“有问题的服务器”

我如何确保程序在每次面对由于密钥问题而提示输入root密码的服务器时都会忽略、跳过并继续使用代码,并且不会挂起密码提示

这是我的密码:

#!/usr/bin/python
from socket import socket
import subprocess, os
def run_command():
ipList = input_ip_addresses() ### A function that receive from the user an infinite loop 
                              ### of ip addresses and then returns the ip addresses 
                              ### as a list.
print '\n Type Linux commands. Type "end" to finish entering commands.'
cmds = []
while True:
    userInput = raw_input("> ")
    if userInput.lower() == "end":
        break
    cmds.append(userInput)
print '\nThanks! Working...\n'
for ipAddr in ipList:
    badConnection = 0
    s = socket()
    s.settimeout(2)
    for currentPort in ("22", "22222"):
        print "INFO: Trying to connect to: {} with port {}".format(ipAddr, currentPort)
        try:
            portSocket = int(currentPort)
            s.connect((ipAddr, portSocket))
            s.close()
        except:
            badConnection += 1
            print "ERROR: Could not connect to {} with port {}".format(ipAddr, currentPort)
            if badConnection == 1:
                continue
        if badConnection == 2:
            break
        for cmd in cmds:
            ssh = subprocess.Popen(['ssh', ipAddr, "-p", currentPort], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, bufsize=0)
            finalCMD = "{} \n".format(cmd)
            ssh.stdin.write(finalCMD)
            ssh.stdin.close()
            sshOutput = ssh.stdout.readlines()
            sshError = ssh.stderr.readlines()
            if len(sshError) > 0:
                for msg in sshError:
                    print msg
            if len(sshOutput) > 0:
                for msg in sshOutput:
                    print msg
            if len(sshOutput) == 0 and len(sshError) == 0:
                msg = 'Command executed successfully'
                print msg
        break
    if badConnection == 2:
        continue

此外,有些服务器使用端口22,有些服务器使用端口2222,因此存在“CurrentPort”情况。

ssh
有几个选项可以更好地进行批处理;
manssh
是你的朋友,不管我在下面写什么,你一定要读:

使用
-o
选项,您可以在
ssh\u配置中指定任何选项。同样,文档是您的朋友,您应该阅读
manssh
manssh\u config
。在你的特殊情况下,你会想要

['ssh', '-o', 'PasswordAuthentication=No', ipAddr, "-p", currentPort]
完全禁用基于密码的登录

无论如何,如果这是一个高吞吐量的东西,也许您不希望为每个连接生成一个SSH进程。看一看python SSH库——它似乎是您要做的事情的首选库


再退一步看看你想要建造的东西:你正在重新发明轮子。试试ansible。这正是您要做的–控制主机列表,它有点侧重于系统维护,因此很容易创建您希望在每台机器上安装的软件包列表,修改配置文件,启动服务,不要太在意目标系统的细节。

请删除代码中多余的空行。这是不必要的难以阅读。据我所知,你忘了问一个问题(也就是说,一个最后有问号的句子
,我们可以回答)。@MarcusMüller谢谢,我修正了它。BatchMode可能有用:非常感谢!添加“PasswordAuthentication=No”完成了任务。现在我有一个公钥,密码的错误,但这种事情我知道如何处理。再次感谢:)