paramiko模塊安裝和使用


一 、安裝

1.1、win10系統

安裝最新版本pip3后,使用pip3 install paramiko命令

E:\>pip3 install paramiko
Collecting paramiko
  Downloading paramiko-2.8.0-py2.py3-none-any.whl (206 kB)
     |████████████████████████████████| 206 kB 24 kB/s
Collecting cryptography>=2.5
  Downloading cryptography-36.0.0-cp36-abi3-win_amd64.whl (2.2 MB)
     |████████████████████████████████| 2.2 MB 38 kB/s
Collecting pynacl>=1.0.1
  Downloading PyNaCl-1.4.0-cp35-abi3-win_amd64.whl (206 kB)
     |████████████████████████████████| 206 kB 16 kB/s
Collecting bcrypt>=3.1.3
  Downloading bcrypt-3.2.0-cp36-abi3-win_amd64.whl (28 kB)
Requirement already satisfied: cffi>=1.12 in c:\users\administrator\appdata\local\programs\python\python39\lib\site-packages (from cryptography>=2.5->paramiko) (1.14.5)
Requirement already satisfied: six in c:\users\administrator\appdata\local\programs\python\python39\lib\site-packages (from pynacl>=1.0.1->paramiko) (1.15.0)
Requirement already satisfied: pycparser in c:\users\administrator\appdata\local\programs\python\python39\lib\site-packages (from cffi>=1.12->cryptography>=2.5->paramiko) (2.20)
Installing collected packages: cryptography, pynacl, bcrypt, paramiko
Successfully installed bcrypt-3.2.0 cryptography-36.0.0 paramiko-2.8.0 pynacl-1.4.0

 

 

1.2、centos系統

yum install python-paramiko

 

二、使用

參考鏈接:https://blog.csdn.net/liulanba/article/details/114596709

paramiko是用python語言寫的一個模塊,遠程連接到Linux服務器,查看上面的日志狀態,批量配置遠程服務器,文件上傳,文件下載等,提供了ssh及sftp進行遠程登錄服務器執行命令和上傳下載文件的功能。

2.1、基於用戶名和密碼實現SSH功能

import paramiko

# 創建SSH對象
ssh = paramiko.SSHClient()
# 允許連接不在known_hosts文件上的主機
# 即允許將信任的主機自動加入到host_allow 列表,此方法必須放在connect方法的前面
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 連接服務器
ssh.connect(hostname="192.168.0.99", port=22, username="root", password="rootroot")
# 執行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 結果放到stdout中,如果有錯誤將放到stderr中
result = stdout.read().decode()
# 獲取錯誤提示(stdout、stderr只會輸出其中一個)
err = stderr.read()
# 關閉連接
ssh.close()
print(stdin, result, err)

 

2.2、基於用戶名和密碼的 transport 方式登錄

前一種方式是傳統的連接服務器、執行命令、關閉的一個操作,有時候需要登錄上服務器執行多個操作,比如執行命令、上傳/下載文件,上面方法則無法實現,可以通過如下方式來操作。

#SSHClient 封裝 Transport
import paramiko
# 實例化一個transport對象
transport = paramiko.Transport(('192.168.199.146', 22))
# 建立連接
transport.connect(username='fishman', password='9')
# 將sshclient的對象的transport指定為以上的transport
ssh = paramiko.SSHClient()
ssh._transport = transport
# 執行命令,和傳統方法一樣
stdin, stdout, stderr = ssh.exec_command('df')
print (stdout.read().decode())
# 關閉連接
transport.close()

 

2.3、基於用戶名和密碼實現SFTP功能

import paramiko
# 連接虛擬機centos上的ip及端口,實例化一個transport對象
transport = paramiko.Transport(("192.168.0.99", 22))
transport.connect(username="root", password="rootroot")
# 將實例化的Transport作為參數傳入SFTPClient中
sftp = paramiko.SFTPClient.from_transport(transport)
# 將“calculator.py”上傳到filelist文件夾中
sftp.put('D:\python庫\Python_shell\day05\calculator.py', '/filelist/calculator.py')
# 將centos中的aaa.txt文件下載到桌面
sftp.get('/filedir/aaa.txt', r'C:\Users\duany_000\Desktop\test_aaa.txt')
transport.close()

 

2.4、使用秘鑰實現SSH功能

import paramiko
private_key = paramiko.RSAKey.from_private_key_file('id_rsa31')
# 創建SSH對象
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 連接服務器
ssh.connect(hostname='192.168.79.9', port=22, username='root', pkey=private_key)
stdin, stdout, stderr = ssh.exec_command('ifconfig')
res_out = stdout.read()
print(res_out.decode())
ssh.close()

 

2.5、基於密鑰的 Transport 方式登錄

# 指定本地的RSA私鑰文件,如果建立密鑰對時設置的有密碼,password為設定的密碼,如無不用指定password參數
pkey = paramiko.RSAKey.from_private_key_file('/home/super/.ssh/id_rsa', password='12345')
# 建立連接
trans = paramiko.Transport(('192.168.2.129', 22))
trans.connect(username='super', pkey=pkey)

# 將sshclient的對象的transport指定為以上的trans
ssh = paramiko.SSHClient()
ssh._transport = trans

# 執行命令,和傳統方法一樣
stdin, stdout, stderr = ssh.exec_command('df -hl')
print(stdout.read().decode())

# 關閉連接
trans.close()

 

2.6、使用秘鑰實現SFTP功能

import paramiko
private_key = paramiko.RSAKey.from_private_key_file('id_rsa31')
# 連接虛擬機centos上的ip及端口
transport = paramiko.Transport(("192.168.79.9", 22))
transport.connect(username="root", pkey=private_key)
# 將實例化的Transport作為參數傳入SFTPClient中
sftp = paramiko.SFTPClient.from_transport(transport)
# 將“calculator.py”上傳到filelist文件夾中
sftp.put('D:\python庫\Python_shell\day05\calculator.py', '/filedir/calculator.py')
# 將centos中的aaa.txt文件下載到桌面
sftp.get('/filedir/oldtext.txt', r'C:\Users\duany_000\Desktop\oldtext.txt')
transport.close()

 

2.7、實現輸入命令立馬返回結果的功能

import paramiko
import os
import select
import sys

# 建立一個socket
trans = paramiko.Transport(('192.168.2.129', 22))
# 啟動一個客戶端
trans.start_client()

# 如果使用rsa密鑰登錄的話
'''
default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
prikey = paramiko.RSAKey.from_private_key_file(default_key_file)
trans.auth_publickey(username='super', key=prikey)
'''
# 如果使用用戶名和密碼登錄
trans.auth_password(username='super', password='super')
# 打開一個通道
channel = trans.open_session()
# 獲取終端
channel.get_pty()
# 激活終端,這樣就可以登錄到終端了,就和我們用類似於xshell登錄系統一樣
channel.invoke_shell()
# 下面就可以執行你所有的操作,用select實現
# 對輸入終端sys.stdin和 通道進行監控,
# 當用戶在終端輸入命令后,將命令交給channel通道,這個時候sys.stdin就發生變化,select就可以感知
# channel的發送命令、獲取結果過程其實就是一個socket的發送和接受信息的過程
while True:
    readlist, writelist, errlist = select.select([channel, sys.stdin,], [], [])
    # 如果是用戶輸入命令了,sys.stdin發生變化
    if sys.stdin in readlist:
        # 獲取輸入的內容
        input_cmd = sys.stdin.read(1)
        # 將命令發送給服務器
        channel.sendall(input_cmd)

    # 服務器返回了結果,channel通道接受到結果,發生變化 select感知到
    if channel in readlist:
        # 獲取結果
        result = channel.recv(1024)
        # 斷開連接后退出
        if len(result) == 0:
            print("\r\n**** EOF **** \r\n")
            break
        # 輸出到屏幕
        sys.stdout.write(result.decode())
        sys.stdout.flush()

# 關閉通道
channel.close()
# 關閉鏈接
trans.close()

 

2.8、支持Tab補全

import paramiko
import os
import select
import sys
import tty
import termios

'''
實現一個xshell登錄系統的效果,登錄到系統就不斷輸入命令同時返回結果
支持自動補全,直接調用服務器終端

'''
# 建立一個socket
trans = paramiko.Transport(('192.168.2.129', 22))
# 啟動一個客戶端
trans.start_client()

# 如果使用rsa密鑰登錄的話
'''
default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
prikey = paramiko.RSAKey.from_private_key_file(default_key_file)
trans.auth_publickey(username='super', key=prikey)
'''
# 如果使用用戶名和密碼登錄
trans.auth_password(username='super', password='super')
# 打開一個通道
channel = trans.open_session()
# 獲取終端
channel.get_pty()
# 激活終端,這樣就可以登錄到終端了,就和我們用類似於xshell登錄系統一樣
channel.invoke_shell()

# 獲取原操作終端屬性
oldtty = termios.tcgetattr(sys.stdin)
try:
    # 將現在的操作終端屬性設置為服務器上的原生終端屬性,可以支持tab了
    tty.setraw(sys.stdin)
    channel.settimeout(0)

    while True:
        readlist, writelist, errlist = select.select([channel, sys.stdin,], [], [])
        # 如果是用戶輸入命令了,sys.stdin發生變化
        if sys.stdin in readlist:
            # 獲取輸入的內容,輸入一個字符發送1個字符
            input_cmd = sys.stdin.read(1)
            # 將命令發送給服務器
            channel.sendall(input_cmd)

        # 服務器返回了結果,channel通道接受到結果,發生變化 select感知到
        if channel in readlist:
            # 獲取結果
            result = channel.recv(1024)
            # 斷開連接后退出
            if len(result) == 0:
                print("\r\n**** EOF **** \r\n")
                break
            # 輸出到屏幕
            sys.stdout.write(result.decode())
            sys.stdout.flush()
finally:
    # 執行完后將現在的終端屬性恢復為原操作終端屬性
    termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)

# 關閉通道
channel.close()
# 關閉鏈接
trans.close()

 

2.9、exec_command()函數

官方解釋為

    def exec_command(
        self,
        command,
        bufsize=-1,
        timeout=None,
        get_pty=False,
        environment=None,
    ):
        """
        Execute a command on the SSH server.  A new `.Channel` is opened and
        the requested command is executed.  The command's input and output
        streams are returned as Python ``file``-like objects representing
        stdin, stdout, and stderr.

        :param str command: the command to execute
        :param int bufsize:
            interpreted the same way as by the built-in ``file()`` function in
            Python
        :param int timeout:
            set command's channel timeout. See `.Channel.settimeout`
        :param bool get_pty:
            Request a pseudo-terminal from the server (default ``False``).
            See `.Channel.get_pty`
        :param dict environment:
            a dict of shell environment variables, to be merged into the
            default environment that the remote command executes within.

            .. warning::
                Servers may silently reject some environment variables; see the
                warning in `.Channel.set_environment_variable` for details.

        :return:
            the stdin, stdout, and stderr of the executing command, as a
            3-tuple

        :raises: `.SSHException` -- if the server fails to execute the command

        .. versionchanged:: 1.10
            Added the ``get_pty`` kwarg.
        """
        chan = self._transport.open_session(timeout=timeout)
        if get_pty:
            chan.get_pty()
        chan.settimeout(timeout)
        if environment:
            chan.update_environment(environment)
        chan.exec_command(command)
        stdin = chan.makefile_stdin("wb", bufsize)
        stdout = chan.makefile("r", bufsize)
        stderr = chan.makefile_stderr("r", bufsize)
        return stdin, stdout, stderr

用法:

ssh.exec_command('cd /home/nvidia/lf && python test.py'print(stdout.read())

這種在命令完成后才顯示信息!但是,執行文件時,如果又不斷輸出,希望輸出一條打印一條,而不是在以后輸出,修改為:

# 執行命令
stdin, stdout, stderr = ssh.exec_command('cd /home/nvidia/lf && python test.py')
for line in iter(stdout.readline, ""):
       print(line, end="")
print('finished.')

 

import paramikoimport osimport selectimport sysimport ttyimport termios
'''實現一個xshell登錄系統的效果,登錄到系統就不斷輸入命令同時返回結果支持自動補全,直接調用服務器終端
'''# 建立一個sockettrans = paramiko.Transport(('192.168.2.129', 22))# 啟動一個客戶端trans.start_client()
# 如果使用rsa密鑰登錄的話'''default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')prikey = paramiko.RSAKey.from_private_key_file(default_key_file)trans.auth_publickey(username='super', key=prikey)'''# 如果使用用戶名和密碼登錄trans.auth_password(username='super', password='super')# 打開一個通道channel = trans.open_session()# 獲取終端channel.get_pty()# 激活終端,這樣就可以登錄到終端了,就和我們用類似於xshell登錄系統一樣channel.invoke_shell()
# 獲取原操作終端屬性oldtty = termios.tcgetattr(sys.stdin)try:    # 將現在的操作終端屬性設置為服務器上的原生終端屬性,可以支持tab了    tty.setraw(sys.stdin)    channel.settimeout(0)
    while True:        readlist, writelist, errlist = select.select([channel, sys.stdin,], [], [])        # 如果是用戶輸入命令了,sys.stdin發生變化        if sys.stdin in readlist:            # 獲取輸入的內容,輸入一個字符發送1個字符            input_cmd = sys.stdin.read(1)            # 將命令發送給服務器            channel.sendall(input_cmd)
        # 服務器返回了結果,channel通道接受到結果,發生變化 select感知到        if channel in readlist:            # 獲取結果            result = channel.recv(1024)            # 斷開連接后退出            if len(result) == 0:                print("\r\n**** EOF **** \r\n")                break            # 輸出到屏幕            sys.stdout.write(result.decode())            sys.stdout.flush()finally:    # 執行完后將現在的終端屬性恢復為原操作終端屬性    termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
# 關閉通道channel.close()# 關閉鏈接trans.close()————————————————版權聲明:本文為CSDN博主「liulanba」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。原文鏈接:https://blog.csdn.net/liulanba/article/details/114596709


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM