paramiko模塊&堡壘機

本節內容html

  paramiko模塊java

  paramiko模塊之SSHClientpython

  paramiko模塊之SFTPClientios

  paramiko模塊之封裝多個遠程操做redis

  堡壘機sql

  一、實現思路shell

  二、表結構數據庫

  三、實現過程windows

  四、window打開終端bash

paramiko模塊

paramiko模塊,基於SSH用於鏈接遠程服務器並執行相關操做。

1、安裝

pip3 install paramiko

  

paramiko模塊之SSHClient

用於鏈接遠程服務器並執行基本命令

基於用戶名密碼鏈接:

import paramiko

# 建立SSH對象
ssh = paramiko.SSHClient()
# 容許鏈接不在know_hosts文件中的主機
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 鏈接服務器
ssh.connect(hostname='172.11.2.109', port=22, username='root', password='founder123')

# 執行命令
# stdin 交互輸入的命令
# stdout 輸出
# stderr 錯誤信息
stdin, stdout, stderr = ssh.exec_command('ls')
# 獲取命令結果
result = stdout.read()
print(result.decode())
'''輸出結果
anaconda-ks.cfg
install.log
install.log.syslog
installServer_nfs.sh
java
latest
redis-3.0.6
redis-3.0.6.tar.gz
sources.list
VMwareTools-9.10.5-2981885.tar.gz
vmware-tools-distrib
'''

 SSHClient 內部封裝 Transport

 1 import paramiko
 2 
 3 transport = paramiko.Transport(('hostname', 22))
 4 transport.connect(username='wupeiqi', password='123')
 5 
 6 ssh = paramiko.SSHClient()
 7 ssh._transport = transport
 8 
 9 stdin, stdout, stderr = ssh.exec_command('df')
10 print stdout.read()
11 
12 transport.close()
SSHClient 封裝 Transport

基於公鑰密鑰鏈接:

import paramiko
  
private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
  
# 建立SSH對象
ssh = paramiko.SSHClient()
# 容許鏈接不在know_hosts文件中的主機
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 鏈接服務器
ssh.connect(hostname='c1.salt.com', port=22, username='wupeiqi', key=private_key)
  
# 執行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 獲取命令結果
result = stdout.read()
  
# 關閉鏈接
ssh.close()
View Code

基於私鑰字符進行鏈接

import paramiko
from io import StringIO

key_str = """-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAq7gLsqYArAFco02/55IgNg0r7NXOtEM3qXpb/dabJ5Uyky/8
NEHhFiQ7deHIRIuTW5Zb0kD6h6EBbVlUMBmwJrC2oSzySLU1w+ZNfH0PE6W6fans
H80whhuc/YgP+fjiO+VR/gFcqib8Rll5UfYzf5H8uuOnDeIXGCVgyHQSmt8if1+e
7hn1MVO1Lrm9Fco8ABI7dyv8/ZEwoSfh2C9rGYgA58LT1FkBRkOePbHD43xNfAYC
tfLvz6LErMnwdOW4sNMEWWAWv1fsTB35PAm5CazfKzmam9n5IQXhmUNcNvmaZtvP
c4f4g59mdsaWNtNaY96UjOfx83Om86gmdkKcnwIDAQABAoIBAQCnDBGFJuv8aA7A
ZkBLe+GN815JtOyye7lIS1n2I7En3oImoUWNaJEYwwJ8+LmjxMwDCtAkR0XwbvY+
c+nsKPEtkjb3sAu6I148RmwWsGncSRqUaJrljOypaW9dS+GO4Ujjz3/lw1lrxSUh
IqVc0E7kyRW8kP3QCaNBwArYteHreZFFp6XmtKMtXaEA3saJYILxaaXlYkoRi4k8
S2/K8aw3ZMR4tDCOfB4o47JaeiA/e185RK3A+mLn9xTDhTdZqTQpv17/YRPcgmwz
zu30fhVXQT/SuI0sO+bzCO4YGoEwoBX718AWhdLJFoFq1B7k2ZEzXTAtjEXQEWm6
01ndU/jhAasdfasdasdfasdfa3eraszxqwefasdfadasdffsFIfAsjQb4HdkmHuC
OeJrJOd+CYvdEeqJJNnF6AbHyYHIECkj0Qq1kEfLOEsqzd5nDbtkKBte6M1trbjl
HtJ2Yb8w6o/q/6Sbj7wf/cW3LIYEdeVCjScozVcQ9R83ea05J+QOAr4nAoGBAMaq
UzLJfLNWZ5Qosmir2oHStFlZpxspax/ln7DlWLW4wPB4YJalSVovF2Buo8hr8X65
lnPiE41M+G0Z7icEXiFyDBFDCtzx0x/RmaBokLathrFtI81UCx4gQPLaSVNMlvQA
539GsubSrO4LpHRNGg/weZ6EqQOXvHvkUkm2bDDJAoGATytFNxen6GtC0ZT3SRQM
WYfasdf3xbtuykmnluiofasd2sfmjnljkt7khghmghdasSDFGQfgaFoKfaawoYeH
C2XasVUsVviBn8kPSLSVBPX4JUfQmA6h8HsajeVahxN1U9e0nYJ0sYDQFUMTS2t8
RT57+WK/0ONwTWHdu+KnaJECgYEAid/ta8LQC3p82iNAZkpWlGDSD2yb/8rH8NQg
9tjEryFwrbMtfX9qn+8srx06B796U3OjifstjJQNmVI0qNlsJpQK8fPwVxRxbJS/
pMbNICrf3sUa4sZgDOFfkeuSlgACh4cVIozDXlR59Z8Y3CoiW0uObEgvMDIfenAj
98pl3ZkCgYEAj/UCSni0dwX4pnKNPm6LUgiS7QvIgM3H9piyt8aipQuzBi5LUKWw
DlQC4Zb73nHgdREtQYYXTu7p27Bl0Gizz1sW2eSgxFU8eTh+ucfVwOXKAXKU5SeI
+MbuBfUYQ4if2N/BXn47+/ecf3A4KgB37Le5SbLDddwCNxGlBzbpBa0=
-----END RSA PRIVATE KEY-----"""

private_key = paramiko.RSAKey(file_obj=StringIO(key_str))
transport = paramiko.Transport(('10.0.1.40', 22))
transport.connect(username='wupeiqi', pkey=private_key)

ssh = paramiko.SSHClient()
ssh._transport = transport

stdin, stdout, stderr = ssh.exec_command('df')
result = stdout.read()

transport.close()

print(result)
View Code

 

paramiko模塊之SFTPClient

  

用於鏈接遠程服務器並執行上傳下載

基於用戶名密碼上傳下載:

import paramiko

transport = paramiko.Transport(('172.11.2.109',22))
transport.connect(username='root',password='founder123')

#建立sftp對象
sftp = paramiko.SFTPClient.from_transport(transport)
# 將location.py 上傳至服務器 /tmp/test.py
sftp.put('/tmp/location.py', '/tmp/test.py')
# 將remove_path 下載到本地 local_path
sftp.get('remove_path', 'local_path')

transport.close()

 

基於公鑰密鑰上傳下載:

import paramiko
  
private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
  
transport = paramiko.Transport(('hostname', 22))
transport.connect(username='wupeiqi', pkey=private_key )
  
sftp = paramiko.SFTPClient.from_transport(transport)
# 將location.py 上傳至服務器 /tmp/test.py
sftp.put('/tmp/location.py', '/tmp/test.py')
# 將remove_path 下載到本地 local_path
sftp.get('remove_path', 'local_path')
  
transport.close()
View Code

paramiko模塊之封裝多個遠程操做

看上面的paramiko執行命令的時候有兩種方法,傳輸文件的時候有一種方法!而且這裏在執行命令的時候鏈接下而後關閉,傳輸文件的時候傳輸完後關閉,這樣不是很好!

那麼咱們能夠鏈接上,而後把執行命令和上傳文件寫成兩個方法操做。

在遠程執行命令的時候實際上是很快的可是他們消耗的時間基本上都在創建鏈接上了,因此咱們要寫成鏈接上一次執行命令或上傳文件所有都完事以後關閉。

import  paramiko
class SSH:
    def __init__(self,host,port,user,pwd):
        self.host = host
        self.port = port
        self.user = user
        self.pwd = pwd

        #定義transport方法
        #self.transport = None

    def connect(self):
        #經過transport鏈接
        self.transport = paramiko.Transport((self.host,self.port))
        self.transport.connect(username=self.user,password=self.pwd)

    def cmd(self,cmd):
        ssh = paramiko.SSHClient()
        ssh._transport = self.transport
        stdin,stdout,stderr = ssh.exec_command(cmd)
        return stdout.read()

    def download(self,server_path,local_path):
        sftp = paramiko.SFTPClient.from_transport(self.transport)
        sftp.get(server_path,local_path)

    def upload(self,server_path,local_path):
        sftp = paramiko.SFTPClient.from_transport(self.transport)
        sftp.put(server_path,local_path)

    def close(self):
        self.transport.close()

obj = SSH('172.11.2.109',22,'root','founder123')
obj.connect()
obj.cmd('ls')
obj.cmd('df')
print(obj.cmd('df').decode())
obj.close()
'''
上面的例子中咱們就鏈接了一次,而後用這一次鏈接進行命令和上傳文件的管理!
不用來回的建立和關閉SSH鏈接
'''

  

import paramiko
import uuid

class SSHConnection(object):

    def __init__(self, host='192.168.11.61', port=22, username='alex',pwd='alex3714'):
        self.host = host
        self.port = port
        self.username = username
        self.pwd = pwd
        self.__k = None

    def run(self):
        self.connect()
        pass
        self.close()

    def connect(self):
        transport = paramiko.Transport((self.host,self.port))
        transport.connect(username=self.username,password=self.pwd)
        self.__transport = transport

    def close(self):
        self.__transport.close()

    def cmd(self, command):
        ssh = paramiko.SSHClient()
        ssh._transport = self.__transport
        # 執行命令
        stdin, stdout, stderr = ssh.exec_command(command)
        # 獲取命令結果
        result = stdout.read()
        return result

    def upload(self,local_path, target_path):
        # 鏈接,上傳
        sftp = paramiko.SFTPClient.from_transport(self.__transport)
        # 將location.py 上傳至服務器 /tmp/test.py
        sftp.put(local_path, target_path)

ssh = SSHConnection()
ssh.connect()
r1 = ssh.cmd('df')
ssh.upload('s2.py', "/home/alex/s7.py")
ssh.close()

Demo

  

堡壘機

 

 

一、實現思路

程序一:
    1、後臺管理
        - 堡壘機上建立用戶和密碼(堡壘機root封裝的類,UserProfile表)
        - .bashrc 
            /usr/bin/python3 /data/bastion.py
            exit
            
    2、後臺管理
        - 服務器上建立用戶和密碼 或 公鑰上傳
        - 服務器帳號 -> 人 關聯
        
程序二:
    3、用戶登陸

        - ssh 堡壘機用戶名@堡壘機IP
        - 獲取當前用戶 os.environ['USER']
        - 獲取當前用戶的主機列表
        - 獲取選中的主機下的全部用戶
        - 選擇任何一個用戶

 

  二、表結構

  1 #!/usr/bin/env python
  2 # -*- coding:utf-8 -*-
  3 #Author:liufeng
  4 
  5 from sqlalchemy import create_engine, and_, or_, func, Table
  6 from sqlalchemy.ext.declarative import declarative_base
  7 from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, DateTime
  8 from sqlalchemy.orm import sessionmaker, relationship
  9 from ..conf.settings import engine
 10 
 11 Base = declarative_base()  # 生成一個SqlORM 基類
 12 
 13 #主機表
 14 class Host(Base):
 15     __tablename__ = 'host'
 16     id = Column(Integer, primary_key=True)
 17     hostname = Column(String(64), unique=True, nullable=False)
 18     ip_addr = Column(String(128), unique=True, nullable=False)
 19     port = Column(Integer, default=22)
 20 
 21 
 22 # 主機用戶表
 23 '''
 24 問題:
 25 一、username是否應該設爲unique,也有多是一個堡壘機用戶,在兩臺服務器上用一個登陸名,好比root帳戶
 26 二、name='_host_username_uc是幹嗎的
 27 '''
 28 class HostUser(Base):
 29     __tablename__ = 'host_user'
 30     id = Column(Integer, primary_key=True, autoincrement=True)
 31     username = Column(String(64), unique=True, nullable=False)
 32     AuthTypes = [
 33         ('p', 'SSH/Password'),
 34         ('r', 'SSH/KEY'),
 35     ]
 36     auth_type = Column(String(16))
 37     cert = Column(String(255))
 38 
 39     host_id = Column(Integer, ForeignKey('host.id'))
 40     #外鍵關聯
 41     host = relationship("Host", backref="host_user")
 42 
 43     __table_args__ = (
 44         UniqueConstraint('host_id', 'username', name='_host_username_uc'),
 45     )
 46 
 47 #用戶組
 48 '''
 49 class Group(Base):
 50     __tablename__ = 'group'
 51     id = Column(Integer, primary_key=True)
 52     name = Column(String(64), unique=True, nullable=False)
 53 '''
 54 
 55 #堡壘機用戶表
 56 class UserProfile(Base):
 57     __tablename__ = 'user_profile'
 58     id = Column(Integer, primary_key=True, autoincrement=True)
 59     username = Column(String(64), unique=True, nullable=False)
 60     password = Column(String(255), nullable=False)
 61 
 62     #多對多關聯
 63     host_user = relationship("host_user", secondary=user_profile_2_host_user, backref="user_profile")
 64 
 65 
 66 
 67 #用戶組與堡壘機關係表
 68 '''
 69 class Group2UserProfile(Base):
 70     __tablename__ = 'group_2_user_profile'
 71     id = Column(Integer, primary_key=True, autoincrement=True)
 72     user_profile_id = Column(Integer, ForeignKey('user_profile.id'))
 73     group_id = Column(Integer, ForeignKey('group.id'))
 74     __table_args__ = (
 75         UniqueConstraint('user_profile_id', 'group_id', name='ux_user_group'),
 76     )
 77 '''
 78 
 79 #用戶組與主機表
 80 '''
 81 class Group2HostUser(Base):
 82     __tablename__ = 'group_2_host_user'
 83     id = Column(Integer, primary_key=True, autoincrement=True)
 84     host_user_id = Column(Integer, ForeignKey('host_user.id'))
 85     group_id = Column(Integer, ForeignKey('group.id'))
 86     __table_args__ = (
 87         UniqueConstraint('group_id', 'host_user_id', name='ux_group_host_user'),
 88     )
 89 '''
 90 
 91 #堡壘機用戶和主機用戶關聯表
 92 '''
 93 class UserProfile2HostUser(Base):
 94     __tablename__ = 'user_profile_2_host_user'
 95     id = Column(Integer, primary_key=True, autoincrement=True)
 96     host_user_id = Column(Integer, ForeignKey('host_user.id'))
 97     user_profile_id = Column(Integer, ForeignKey('user_profile.id'))
 98     __table_args__ = (
 99         UniqueConstraint('user_profile_id', 'host_user_id', name='ux_user_host_user'),
100     )
101 '''
102 user_profile_2_host_user = Table("user_profile_2_host_user",Base.metadata,
103                           Column(Integer, ForeignKey('host_user.id')),
104                           Column(Integer, ForeignKey('user_profile.id')),
105                           __table_args__ = (
106                             UniqueConstraint('user_profile_id', 'host_user_id', name='ux_user_host_user')
107                           )
108                           )
109 
110 #日誌表
111 class AuditLog(Base):
112     __tablename__ = 'audit_log'
113     id = Column(Integer, primary_key=True)
114     '''
115     日誌記錄命令、登陸,登出三種狀態
116     '''
117     action_choices2 = [
118         (u'cmd', u'CMD'),
119         (u'login', u'Login'),
120         (u'logout', u'Logout'),
121     ]
122     action_type = Column(String(16))
123     log = Column(String(255))
124     date = Column(DateTime)
125     user_profile_id = Column(Integer, ForeignKey('user_profile.id'))
126     host_user_id = Column(Integer, ForeignKey('host_user.id'))
127     #添加多外鍵關聯
128     user_profile_id = relationship("audit_log",foreign_keys=[user_profile_id])
129     host_user_id = relationship("audit_log", foreign_keys=[host_user_id])
表結構

 

  三、實現過程

  

import paramiko
import os
import sys
import select
import socket

tran = paramiko.Transport(('192.168.7.100', 22,))
tran.start_client()

'''
#使用密鑰認證
default_path = os.path.join(os.environ['root'], '.ssh', 'id_rsa')
key = paramiko.RSAKey.from_private_key_file(default_path)
tran.auth_publickey('root', key)
'''
tran.auth_password('root', 'nihao123!') #經過密碼認證
chan = tran.open_session()# 打開一個通道
chan.get_pty()# 獲取一個終端
chan.invoke_shell()# 激活器

'''
# 利用sys.stdin,肆意妄爲執行操做
# 用戶在終端輸入內容,並將內容發送至遠程服務器
# 遠程服務器執行命令,並將結果返回
# 用戶終端顯示內容
'''
while True:
    # 監視用戶輸入和服務器返回數據
    # sys.stdin 處理用戶輸入
    # chan 是以前建立的通道,用於接收服務器返回信息
    readable, writeable, error = select.select([chan, sys.stdin, ],[],[],1)  #監視chen和終端
    #只要發生變化,chan或者stdin或者都變化
    if chan in readable: #遠端有變化後捕獲到
        try:
            x = chan.recv(1024)
            #ssh鏈接後他發送接收數據也是經過socket來作的
            if len(x) == 0:
                print '\r\n*** EOF\r\n',
                break
            sys.stdout.write(x)#把內容輸入到終端上
            sys.stdout.flush()
        except socket.timeout:
            pass
    if sys.stdin in readable: #當終端有輸入捕獲到以後
        inp = sys.stdin.readline() #把用戶的那一行輸入
        chan.sendall(inp)#發送命令至遠端

chan.close()
tran.close()
一行行讀入命令

#上面的例子中在捕獲輸出的時候咱們輸入的一行命令(字符串)回車以後,sys.stdin才捕獲到,這個是默認的終端是這樣的,咱們就能夠打開一個文件記錄用戶的全部命令操做

 1 #!/usr/bin/env python
 2 #-*- coding:utf-8 -*-
 3 __author__ = 'luo_t'
 4 import paramiko
 5 import os
 6 import sys
 7 import select
 8 import socket
 9 
10 tran = paramiko.Transport(('192.168.7.100', 22,))
11 tran.start_client()
12 
13 '''
14 #使用密鑰認證
15 default_path = os.path.join(os.environ['root'], '.ssh', 'id_rsa')
16 key = paramiko.RSAKey.from_private_key_file(default_path)
17 tran.auth_publickey('root', key)
18 '''
19 tran.auth_password('root', 'nihao123!') #經過密碼認證
20 chan = tran.open_session()# 打開一個通道
21 chan.get_pty()# 獲取一個終端
22 chan.invoke_shell()# 激活器
23 
24 '''
25 # 利用sys.stdin,肆意妄爲執行操做
26 # 用戶在終端輸入內容,並將內容發送至遠程服務器
27 # 遠程服務器執行命令,並將結果返回
28 # 用戶終端顯示內容
29 '''
30 log = open('record','ab') #打開一個文件記錄用戶的輸入
31 while True:
32     # 監視用戶輸入和服務器返回數據
33     # sys.stdin 處理用戶輸入
34     # chan 是以前建立的通道,用於接收服務器返回信息
35     readable, writeable, error = select.select([chan, sys.stdin, ],[],[],1)  #堅挺chen和終端
36     #只要發生變化,chan或者stdin或者都變化
37     if chan in readable: #遠端有變化後捕獲到
38         try:
39             x = chan.recv(1024)
40             #ssh鏈接後他發送接收數據也是經過socket來作的
41             if len(x) == 0:
42                 log.close() #關閉文件
43                 print '\r\n************************ EOF ************************\r\n',
44                 break
45             sys.stdout.write(x)#把內容輸入到終端上
46             sys.stdout.flush()
47         except socket.timeout:
48             pass
49     if sys.stdin in readable: #當終端有輸入捕獲到以後
50         inp = sys.stdin.readline() #把用戶的那一行輸入
51         log.write(inp) #記錄命令
52         chan.sendall(inp)#發送命令至遠端
53 
54 chan.close()
55 tran.close()
56 
57 open_terminal_write_log
一個字符--> stdin

#還有個例子是咱們在終端輸入命令的時候,常常忘記命令所有的字符。

#默認換行,對於特殊字符特殊處理,好比Ctrl+c

#改變終端默認由行+回車-->stdin,改成一個字符--> stdin

 

首先咱們要作的就是修改終端模式:把原來的默認換行爲「回車」,特殊字符特殊處理,改成輸入一個字符就捕獲而且

#!/usr/bin/env python
#-*- coding:utf-8 -*-
__author__ = 'luo_t'
import paramiko
import os
import sys
import select
import socket
import termios
import tty


tran = paramiko.Transport(('192.168.7.100', 22,))
tran.start_client()

'''
#使用密鑰認證
default_path = os.path.join(os.environ['root'], '.ssh', 'id_rsa')
key = paramiko.RSAKey.from_private_key_file(default_path)
tran.auth_publickey('root', key)
'''
tran.auth_password('root', 'nihao123!') #經過密碼認證
chan = tran.open_session()# 打開一個通道
chan.get_pty()# 獲取一個終端
chan.invoke_shell()# 激活器

'''
# 利用sys.stdin,肆意妄爲執行操做
# 用戶在終端輸入內容,並將內容發送至遠程服務器
# 遠程服務器執行命令,並將結果返回
# 用戶終端顯示內容
'''
# 獲取原tty屬性
oldtty = termios.tcgetattr(sys.stdin)
try:
    # 爲tty設置新屬性
    # 默認當前tty設備屬性:
    #   輸入一行回車,執行
    #   CTRL+C 進程退出,遇到特殊字符,特殊處理。

    # 這是爲原始模式,不認識全部特殊符號
    # 放置特殊字符應用在當前終端,如此設置,將全部的用戶輸入均發送到遠程服務器
    tty.setraw(sys.stdin.fileno()) #把遠端更換爲LINUX原始模式
    chan.settimeout(0.0)

    while True:
        # 監視 用戶輸入 和 遠程服務器返回數據(socket)
        # 阻塞,直到句柄可讀
        r, w, e = select.select([chan, sys.stdin], [], [], 1)
        if chan in r:
            try:
                x = chan.recv(1024)
                if len(x) == 0:
                    print '\r\n*** EOF\r\n',
                    break
                sys.stdout.write(x)
                sys.stdout.flush()
            except socket.timeout:
                pass
        if sys.stdin in r:
            x = sys.stdin.read(1)
            if len(x) == 0:
                break
            chan.send(x)

finally:
    # 從新設置終端屬性
    termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
chan.close()
tran.close()

open_terminal_complemented
View Code

記錄日誌,而且不記錄tab輸入

#!/usr/bin/env python
#-*- coding:utf-8 -*-
__author__ = 'luo_t'
import paramiko
import os
import sys
import select
import socket
import termios
import tty


tran = paramiko.Transport(('192.168.7.100', 22,))
tran.start_client()

'''
#使用密鑰認證
default_path = os.path.join(os.environ['root'], '.ssh', 'id_rsa')
key = paramiko.RSAKey.from_private_key_file(default_path)
tran.auth_publickey('root', key)
'''
tran.auth_password('root', 'nihao123!') #經過密碼認證
chan = tran.open_session()# 打開一個通道
chan.get_pty()# 獲取一個終端
chan.invoke_shell()# 激活器

'''
# 利用sys.stdin,肆意妄爲執行操做
# 用戶在終端輸入內容,並將內容發送至遠程服務器
# 遠程服務器執行命令,並將結果返回
# 用戶終端顯示內容
'''
# 獲取原tty屬性
oldtty = termios.tcgetattr(sys.stdin)
#打開文件

try:
    # 爲tty設置新屬性
    # 默認當前tty設備屬性:
    #   輸入一行回車,執行
    #   CTRL+C 進程退出,遇到特殊字符,特殊處理。

    # 這是爲原始模式,不認識全部特殊符號
    # 放置特殊字符應用在當前終端,如此設置,將全部的用戶輸入均發送到遠程服務器
    tty.setraw(sys.stdin.fileno()) #把遠端更換爲LINUX原始模式
    chan.settimeout(0.0)
    user_log = open('terminalnew_log','ab')
    while True:
        # 監視 用戶輸入 和 遠程服務器返回數據(socket)
        # 阻塞,直到句柄可讀
        r, w, e = select.select([chan, sys.stdin], [], [], 1)
        if chan in r:
            try:
                x = chan.recv(1024)
                if len(x) == 0:
                    user_log.close()
                    print '\r\n*** EOF\r\n',
                    break
                sys.stdout.write(x)
                sys.stdout.flush()
            except socket.timeout:
                pass
        if sys.stdin in r:
            x = sys.stdin.read(1)
            if len(x) == 0:
                break
            if x == '\t': #判斷用戶的是否爲tab若是爲tab將不記錄
                pass
            else:
                user_log.write(x)#若是用戶輸入的命令保存至日誌
            chan.send(x)

finally:
    # 從新設置終端屬性
    termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
chan.close()
tran.close()

open_terminal_complemented_new
View Code

 

  四、window打開終端

 

#!/usr/bin/env python
#-*- coding:utf-8 -*-
__author__ = 'luo_t'
import paramiko
import sys
import threading

tran = paramiko.Transport(('192.168.0.111', 22,))
tran.start_client()

'''
#使用密鑰認證
default_path = os.path.join(os.environ['root'], '.ssh', 'id_rsa')
key = paramiko.RSAKey.from_private_key_file(default_path)
tran.auth_publickey('root', key)
'''
tran.auth_password('root', 'nihao123!') #經過密碼認證
chan = tran.open_session()# 打開一個通道
chan.get_pty()# 獲取一個終端
chan.invoke_shell()# 激活器

'''
# 利用sys.stdin,肆意妄爲執行操做
# 用戶在終端輸入內容,並將內容發送至遠程服務器
# 遠程服務器執行命令,並將結果返回
# 用戶終端顯示內容
'''
sys.stdout.write("Line-buffered terminal emulation. Press F6 or ^Z to send EOF.\r\n\r\n")

def writeall(sock):
    while True:
        data = sock.recv(256)
        '''
        SSH發送數據的也是經過socket進行發送數據的,那麼咱們就可使用socket來獲取遠程機器發送回來的數據。
        while循環一直接收數據,sock.recv(256)是阻塞的只有數據過來的時候纔會繼續走。
        '''
        if not data:
            sys.stdout.write('\r\n*** EOF ***\r\n\r\n')
            sys.stdout.flush()
            break
        sys.stdout.write(data)
        sys.stdout.flush()

writer = threading.Thread(target=writeall, args=(chan,)) #建立了一個線程,去執行writeall方法,參數爲chan(創建的SSH鏈接)
writer.start()

try:
    while True: #主線程循環
        d = sys.stdin.read(1)  #一直監聽用戶的輸入,輸入一個發送一個
        if not d:
            break
        chan.send(d)
except EOFError:
    # user hit ^Z or F6
    pass

chan.close()
tran.close()

open_terminal_complemented_windows
View Code

 

更多請參考:

http://www.cnblogs.com/wupeiqi/articles/5699254.html

http://www.cnblogs.com/luotianshuai/p/5131053.html

數據庫參考:

http://www.cnblogs.com/fengdao/p/6365787.html

http://www.cnblogs.com/lianzhilei/p/6013847.html

相關文章
相關標籤/搜索