通过Python在脚本中使用密码ssh到远程机器

5
我正在使用远程机器。每次需要验证文件更新时间时,我都必须进行ssh,而且有多个脚本将进行ssh到远程机器。 我查看了互联网,但没有找到符合我的要求的内容。
我正在尝试找到一个Python脚本,它使用ssh,密码也在脚本中,因为我的Python脚本将每5分钟检查文件修改时间,我不能每次执行脚本时输入密码。 我尝试了来自SO和互联网的这些代码,但无法满足我的需求。 通过在Python中使用脚本给出密码建立ssh会话 如何使用Python远程执行进程 此外,我通过ssh简单地进入了一个远程机器。然后,我尝试通过Python脚本以ssh的方式连接到另一台远程机器,因为这个Python脚本还包括检查不同文件的修改时间的代码..意味着我已经通过ssh连接到了一个远程机器,然后我想从那里运行一些Python脚本,这些脚本将检查另一台远程机器上文件的修改时间。 是否有一种简单的方法在Python脚本中ssh远程机器并附带密码。 我将不胜感激。

为什么不设置 ssh keys 呢?这样你就不需要输入密码了。 - Macintosh_89
@Macintosh_89,我正在从一台远程机器上运行一些脚本到另一台远程机器上。也就是说,我已经通过ssh连接到了一台远程机器,然后在该机器上运行一些Python脚本,检查另一台远程机器上文件的修改时间。因此,我正在寻找一个包含ssh到远程机器以及密码选项的简单脚本。 - robbin
@Macintosh_89 但我会尝试你的建议。 - robbin
看一下 paramikosshpass - user7141836
1
你还可以使用subprocess.call()与bash命令expect结合使用。请参考以下链接:https://dev59.com/_2Qn5IYBdhLWcg3wVFsv和https://dev59.com/jW445IYBdhLWcg3wmLdd - alec_djinn
@alec_djinn 你的意思是在 Python 脚本中使用这些 Bash 命令吗? - robbin
2个回答

3
如果您想尝试paramiko模块,这里有一个可用的Python脚本示例。
import paramiko

def start_connection():
    u_name = 'root'
    pswd = ''
    port = 22
    r_ip = '198.x.x.x'
    sec_key = '/mycert.ppk'

    myconn = paramiko.SSHClient()
    myconn.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    my_rsa_key = paramiko.RSAKey.from_private_key_file(sec_key)

    session = myconn.connect(r_ip, username =u_name, password=pswd, port=port,pkey=my_rsa_key)

    remote_cmd = 'ifconfig'
    (stdin, stdout, stderr) = myconn.exec_command(remote_cmd)
    print("{}".format(stdout.read()))
    print("{}".format(type(myconn)))
    print("Options available to deal with the connectios are many like\n{}".format(dir(myconn)))
    myconn.close()


if __name__ == '__main__':
    start_connection()

1
ssh是一种安全协议,使用密钥对来确保连接的安全性。请查看此链接:https://www.ssh.com/ssh/protocol/。 sec_key='/mycert.ppk'是我的私钥的绝对路径。您或机器应该拥有一个私钥。 - Ajay2588
谢谢,我会尝试一下。希望它能解决我的问题。我对SSH和远程机器连接还不熟悉,所以才会问。 - robbin
没关系,如果脚本还不清楚,你可以问我。 - Ajay2588
我在远程机器上安装了paramiko,然后收到enum模块未定义的错误。我安装了它,现在显示“ImportError: No module named pyasn1.type.univ”。有什么办法解决这个错误吗? - robbin
客户端[您的机器],远程服务器[您要连接的机器]。paramiko只需要在客户端机器上安装。在上面的代码段中,将 r_ip = '198.x.x.x' 替换为您想要连接的远程服务器的IP地址。我相信用户将是 root,如果不是,则使用预期的用户名。一切都应该正常工作。试试看。 - Ajay2588
显示剩余4条评论

0

在这里也添加我的程序,它依赖于用户密码并在不同的输出文件上显示状态。

#!/bin/python3
import threading, time, paramiko, socket, getpass
from queue import Queue
locke1 = threading.Lock()
q = Queue()

#Check the login
def check_hostname(host_name, pw_r):
    with locke1:
        print ("Checking hostname :"+str(host_name)+" with " + threading.current_thread().name)
        file_output = open('output_file','a')
        file_success = open('success_file','a')
        file_failed = open('failed_file','a')
        file_error = open('error_file','a')
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        try:
          ssh.connect(host_name, username='root', password=pw_r, timeout=5)
          #print ("Success")
          file_success.write(str(host_name+"\n"))
          file_success.close()
          file_output.write("success: "+str(host_name+"\n"))
          file_output.close()

          # printing output if required from remote machine
          #stdin,stdout,stderr = ssh.exec_command("hostname&&uptime")
          #for line in stdout.readlines():
           # print (line.strip())

        except paramiko.SSHException:
                # print ("error")
                file_failed.write(str(host_name+"\n"))
                file_failed.close()
                file_output.write("failed: "+str(host_name+"\n"))
                file_output.close()
                #quit()
        except paramiko.ssh_exception.NoValidConnectionsError:
                #print ("might be windows------------")
                file_output.write("failed: " + str(host_name + "\n"))
                file_output.close()
                file_failed.write(str(host_name+"\n"))
                file_failed.close()
                #quit()
        except socket.gaierror:
          #print ("wrong hostname/dns************")
          file_output.write("error: "+str(host_name+"\n"))
          file_output.close()
          file_error.write(str(host_name + "\n"))
          file_error.close()

        except socket.timeout:
           #print ("No Ping %%%%%%%%%%%%")
           file_output.write("error: "+str(host_name+"\n"))
           file_output.close()
           file_error.write(str(host_name + "\n"))
           file_error.close()

        ssh.close()


def performer1():
    while True:
        hostname_value = q.get()
        check_hostname(hostname_value,pw_sent)
        q.task_done()

if __name__ == '__main__':

    print ("This script checks all the hostnames in the input_file with your standard password and write the outputs in below files: \n1.file_output\n2.file_success \n3.file_failed \n4.file_error \n")

    f = open('output_file', 'w')
    f.write("-------Output of all hosts-------\n")
    f.close()
    f = open('success_file', 'w')
    f.write("-------Success hosts-------\n")
    f.close()
    f = open('failed_file', 'w')
    f.write("-------Failed hosts-------\n")
    f.close()
    f = open('error_file', 'w')
    f.write("-------Hosts with error-------\n")
    f.close()

    with open("input_file") as f:
        hostname1 = f.read().splitlines()

#Read the standard password from the user
    pw_sent=getpass.getpass("Enter the Password:")
    start_time1 = time.time()

    for i in hostname1:
        q.put(i)
    #print ("all the hostname : "+str(list(q.queue)))
    for no_of_threads in range(10):
        t = threading.Thread(target=performer1)
        t.daemon=True
        t.start()

    q.join()
    print ("Check output files for results")
    print ("completed task in" + str(time.time()-start_time1) + "seconds")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接