欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用paramiko遠程執(zhí)行命令、下發(fā)文件的實例

 更新時間:2017年10月01日 08:37:40   作者:agnewee  
下面小編就為大家?guī)硪黄褂胮aramiko遠程執(zhí)行命令、下發(fā)文件的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

寫部署腳本時,難免涉及到一些遠程執(zhí)行命令或者傳輸文件。

之前一直使用sh庫,調(diào)用sh.ssh遠程執(zhí)行一些命令,sh.scp傳輸文件,但是實際使用中還是比較麻煩的,光是模擬用戶登陸這一點,還需要單獨定義方法模擬輸入。

感受一下:

from sh import ssh
PASS = 'xxxx'
def ssh_interact(line, stdin):
  line = line.strip()
  print(line)
  if line.endswith('password:'):
    stdin.put(PASS)
ssh('x.x.x.x', _out=ssh_interact)

來自官方文檔

后來發(fā)現(xiàn)paramiko庫更加優(yōu)雅、便捷,所以準備用pramiko替換掉sh。

之前通過同事了解到,paramiko在遠程執(zhí)行python腳本時,腳本中的輸出內(nèi)容可能會通過stderr這個管道輸出出來,所以直接用paramiko的SSHClient類中的exec_command方法執(zhí)行,通過讀stderr管道中有無輸出來判斷命令是否成功執(zhí)行的方式是行不通的。所以用更底層一些的Channel類的recv_exit_status方法判斷執(zhí)行退出碼更好一些。

安裝

可以通過使用pip install paramiko安裝,細節(jié)這里不再贅述。

封裝

首先定義幾個異常

# coding: utf-8
import os.path

from paramiko import SSHClient, AutoAddPolicy, AuthenticationException


class ConnectError(Exception):
  """
  連接錯誤時拋出的異常
  """
  pass

class RemoteExecError(Exception):
  """
  遠程執(zhí)行命令,失敗時拋出的異常
  """
  pass

class SCPError(Exception):
  """
  遠程下發(fā)文件時拋出的異常
  """
  pass
...
class Remote(object):
  def __init__(self, host, username, password=None, port=22, key_filename=None):
    self.host = host
    self.username = username
    self.password = password
    self.port = port
    self.key_filename = key_filename
    self._ssh = None

  def _connect(self):
    self._ssh = SSHClient()
    self._ssh.set_missing_host_key_policy(AutoAddPolicy())
    try:
      if self.key_filename:
        self._ssh.connect(self.host, username=self.username, port=self.port, key_filename=self.key_filename)
      else:
        self._ssh.connect(self.host, username=self.username, password=self.password, port=self.port)
    except AuthenticationException: 
      self._ssh = None
      raise ConnectionError('連接失敗,請確認用戶名、密碼、端口或密鑰文件是否有效')
    except Exception as e:
      self._ssh = None
      raise ConnectionError('連接時出現(xiàn)意料外的錯誤:%s' % e)

  def get_ssh(self):
    if not self._ssh:
      self._connect()
    return self._ssh

實例化SSHClient類,通過它的connect()方法獲取SSH連接。

需要注意的是,遠程訪問的主機若是第一次連接,屬于未知設(shè)備需要認證,通過set_missing_host_key_policy()方法設(shè)置一種策略,這里使用的是AutoAddPolicy()。

這里的_connect支持兩種方式登錄,一種是提供主機的用戶名密碼,另一種是通過密鑰文件。在連接時檢查如果指定了密鑰文件則使用這種方式登錄,否則通過用戶名密碼登錄。

_connect()雖然是實際的建立連接的方法,但實際對外接口是get_ssh(),如果已經(jīng)有建立好的SSH連接直接返回,避免重復(fù)建立連接。

class Remote(object):
  ...
  def ssh(self, cmd, root_password=None, get_pty=False, super=False):
    cmd = self._prepare_cmd(cmd, root_password, super)
    stdout = self._exec(cmd, get_pty)
    return stdout

  def _prepare_cmd(self, cmd, root_password=None, super=False):
    if self.username != 'root' and super:
      if root_password:
        cmd = "echo '{}'|su - root -c '{}'".format(root_password, cmd)
      else:
        cmd = "echo '{}'|sudo -p '' -S su - root -c '{}'".format(self.password, cmd)
    return cmd

  def _exec(self, cmd, gty_pty=False):
    channel = self.get_ssh().get_transport().open_session()
    if get_pty:
      channel.get_pty()
    channel.exec_command(cmd)
    stdout = channel.makefile('r', -1).readlines()
    stderr = channel.makefile_stderr('r', -1).readlines()
    ret_code = channel.recv_exit_status()
    if ret_code:
      msg = ''.join(stderr) if stderr else ''.join(stdout)
      raise RemoteExecError(msg)
    return stdout

在遠程執(zhí)行某些命令時,可能需要管理員權(quán)限,這種時候需要做一些判斷,首先判斷登錄提供的用戶名如果不是root,則需要對命令做一些修改。這里的修改有兩種情況,一是,該普通用戶本身就有sudo權(quán)限,只需要把執(zhí)行的命令加到sudo之后執(zhí)行就可以,還有一種是普通用戶沒有sudo權(quán)限,需要通過su先切換到root身份之后再執(zhí)行,這種情況下需要提供root密碼。

還有一點要注意的是get_pty這個參數(shù),實際在遠程執(zhí)行sudo命令時,一般主機都會需要通過tty才能執(zhí)行,通過把get_pty值設(shè)置為True,可以模擬tty,但是隨之而來也會有一個問題,如果是遠程執(zhí)行一個需要長期運行的進程,例如啟動nginx服務(wù),當(dāng)遠程命令執(zhí)行后SSH退出之后,此次運行的所有程序也會隨之結(jié)束,所以在需要通過遠程命令運行某些服務(wù)或程序時,是不能指定get_pty參數(shù)的;但同時,如果是普通用戶遠程登錄,是沒有權(quán)限執(zhí)行service命令的。建議的一種方式是修改/etc/sudoers配置文件,注釋掉Defaults requiretty這行。

class Remote(object):
  ...

  def scp(self, local_file, remote_path):
    if not os.path.exists(local_file):
      raise SCPError("Local %s isn't exists" % local_file)
    if not os.path.isfile(local_file):
      raise SCPError("%s is not a File" % local_file)
    sftp = self.get_ssh().open_sftp()
    try:
      sftp.put(local_file, remote_path)
    except Exception as e:
      raise SCPError(e)

先確認要下發(fā)的文件存在,并且是文件不是目錄,如果不是則拋出異常。同時,remote_path需要是遠程主機的文件絕對目錄,例如/tmp/xxx.xxx,而不能是/tmp。

使用

# coding: utf-8
from remote_client import RemoteClient

rc = RemoteClient('10.1.100.1', 'test', 'test_pass')
rc.ssh('whoami')  # [u'test\n']
rc.scp('/tmp/test.out', '/tmp/test.out')

總結(jié)

相較于sh,paramiko好用的不是一星半點,這里只是提供了一個簡單的封裝,paramiko本身還有很多其他用法,歡迎大家積極討論。

以上只是本人的一點理解,如果有錯誤之處,歡迎指正。

以上這篇使用paramiko遠程執(zhí)行命令、下發(fā)文件的實例就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 在Tensorflow中查看權(quán)重的實現(xiàn)

    在Tensorflow中查看權(quán)重的實現(xiàn)

    今天小編就為大家分享一篇在Tensorflow中查看權(quán)重的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01
  • Python?matplotlib實現(xiàn)多子圖布局

    Python?matplotlib實現(xiàn)多子圖布局

    多子圖布局是指在一個圖像中同時顯示多個子圖,每個子圖可以是獨立的圖形或者是相互關(guān)聯(lián)的圖形,下面我們就來了解下matplotlib是如何實現(xiàn)多子圖布局的吧
    2023-12-12
  • Python threading的使用方法解析

    Python threading的使用方法解析

    這篇文章主要介紹了Python threading的使用方法解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-08-08
  • Python Pandas中創(chuàng)建Series的三種方法總結(jié)

    Python Pandas中創(chuàng)建Series的三種方法總結(jié)

    這篇文章主要介紹了Python Pandas中創(chuàng)建Series的三種方法總結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • python lxml中etree的簡單應(yīng)用

    python lxml中etree的簡單應(yīng)用

    這篇文章主要介紹了python lxml中etree的簡單應(yīng)用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • python下實現(xiàn)二叉堆以及堆排序的示例

    python下實現(xiàn)二叉堆以及堆排序的示例

    下面小編就為大家?guī)硪黄猵ython下實現(xiàn)二叉堆以及堆排序的示例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • Python隨機生成均勻分布在三角形內(nèi)或者任意多邊形內(nèi)的點

    Python隨機生成均勻分布在三角形內(nèi)或者任意多邊形內(nèi)的點

    這篇文章主要為大家詳細介紹了Python隨機生成均勻分布在三角形內(nèi)或者任意多邊形內(nèi)的點,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • python tkinter GUI繪制,以及點擊更新顯示圖片代碼

    python tkinter GUI繪制,以及點擊更新顯示圖片代碼

    這篇文章主要介紹了python tkinter GUI繪制,以及點擊更新顯示圖片代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • Python基礎(chǔ)學(xué)習(xí)之認識線程

    Python基礎(chǔ)學(xué)習(xí)之認識線程

    這篇文章主要介紹了Python線程,這篇開始我們將進入中級編程。處理更加復(fù)雜事情。比如本文的線程,咱們先從基礎(chǔ)知識入手,需要的朋友可以參考下下面文章的詳細內(nèi)容
    2022-02-02
  • Python字符串和其常用函數(shù)合集

    Python字符串和其常用函數(shù)合集

    這篇文章主要給大介紹Python字符串和分享其常用函數(shù)合集,字符串、首字母大寫定義、所有字母大寫、所有字母小寫等函數(shù),具有一定的參考價值,需要的朋友可以參考一下
    2022-03-03

最新評論