最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python獲取交互式ssh shell的方法

 更新時間:2019年02月14日 09:00:39   作者:zlucifer  
今天小編就為大家分享一篇python獲取交互式ssh shell的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

更新,最近在學(xué)unix環(huán)境編程,了解一下進程的創(chuàng)建過程,用最原始的方式實現(xiàn)了一個ssh命令的執(zhí)行。

#coding=utf8
 
'''
用python實現(xiàn)了一個簡單的shell,了解進程創(chuàng)建
類unix 環(huán)境下 fork和exec 兩個系統(tǒng)調(diào)用完成進程的創(chuàng)建
'''
 
import sys, os
 
 
def myspawn(cmdline):
 argv = cmdline.split()
 if len(argv) == 0:
  return 
 program_file = argv[0]
 pid = os.fork()
 if pid < 0:
  sys.stderr.write("fork error")
 elif pid == 0:
  # child
  os.execvp(program_file, argv)
  sys.stderr.write("cannot exec: "+ cmdline)
  sys.exit(127)
 # parent
 pid, status = os.waitpid(pid, 0)
 ret = status >> 8 # 返回值是一個16位的二進制數(shù)字,高8位為退出狀態(tài)碼,低8位為程序結(jié)束系統(tǒng)信號的編號
 signal_num = status & 0x0F
 sys.stdout.write("ret: %s, signal: %s\n" % (ret, signal_num))
 return ret
 
 
def ssh(host, user, port=22, password=None):
 if password:
  sys.stdout.write("password is: '%s' , plz paste it into ssh\n" % (password))
 cmdline = "ssh %s@%s -p %s " % (user, host, port)
 ret = myspawn(cmdline)
 
 
if __name__ == "__main__":
 host = ''
 user = ''
 password = ''
 ssh(host, user, password=password)

最近在做一個項目,需要在客戶端集成一個交互式ssh功能,大概就是客戶端跟服務(wù)器申請個可用的機器,服務(wù)端返回個ip,端口,密碼, 然后客戶端就可以直接登錄到機器上操做了。該程序基于paramiko模塊。

經(jīng)查找,從paramiko的源碼包demos目錄下,可以看到交互式shell的實現(xiàn),就是那個demo.py。但是用起來有些bug,于是我給修改了一下interactive.py(我把windows的代碼刪掉了,剩下的只能在linux下用)。代碼如下:

#coding=utf-8
import socket
import sys
import os
import termios
import tty
import fcntl
import signal
import struct
import select
 
now_channel = None
 
def interactive_shell(chan):
 posix_shell(chan)
 
 
def ioctl_GWINSZ(fd):
 try:
  cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,'aaaa'))
 except:
  return
 return cr
 
 
def getTerminalSize():
 cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
 return int(cr[1]), int(cr[0])
 
 
def resize_pty(signum=0, frame=0):
 width, height = getTerminalSize()
 if now_channel is not None:
  now_channel.resize_pty(width=width, height=height)
 
 
 
def posix_shell(chan):
 global now_channel
 now_channel = chan
 resize_pty()
 signal.signal(signal.SIGWINCH, resize_pty) # 終端大小改變時,修改pty終端大小
 stdin = os.fdopen(sys.stdin.fileno(), 'r', 0) # stdin buff置為空,否則粘貼多字節(jié)或者按方向鍵的時候顯示不正確
 fd = stdin.fileno()
 oldtty = termios.tcgetattr(fd)
 newtty = termios.tcgetattr(fd)
 newtty[3] = newtty[3] | termios.ICANON
 try:
  termios.tcsetattr(fd, termios.TCSANOW, newtty)
  tty.setraw(fd)
  tty.setcbreak(fd)
  chan.settimeout(0.0)
  while True:
   try:
    r, w, e = select.select([chan, stdin], [], [])
   except:
    # 解決SIGWINCH信號將休眠的select系統(tǒng)調(diào)用喚醒引發(fā)的系統(tǒng)中斷,忽略中斷重新調(diào)用解決。
    continue
   if chan in r:
    try:
     x = chan.recv(1024)
     if len(x) == 0:
      print 'rn*** EOFrn',
      break
     sys.stdout.write(x)
     sys.stdout.flush()
    except socket.timeout:
     pass
   if stdin in r:
    x = stdin.read(1)
    if len(x) == 0:
     break
    chan.send(x)
 finally:
  termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)

使用示例:

#coding=utf8
import paramiko
import interactive
 
 
#記錄日志
paramiko.util.log_to_file('/tmp/aaa')
#建立ssh連接
ssh=paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.168.1.11',port=22,username='hahaha',password='********',compress=True)
 
#建立交互式shell連接
channel=ssh.invoke_shell()
#建立交互式管道
interactive.interactive_shell(channel)
#關(guān)閉連接
channel.close()
ssh.close()

interactive.py代碼中主要修復(fù)了幾個問題:

1、當(dāng)讀取鍵盤輸入時,方向鍵會有問題,因為按一次方向鍵會產(chǎn)生3個字節(jié)數(shù)據(jù),我的理解是按鍵一次會被select捕捉一次標準輸入有變化,但是我每次只處理1個字節(jié)的數(shù)據(jù),其他的數(shù)據(jù)會存放在輸入緩沖區(qū)中,等待下次按鍵的時候一起發(fā)過去。這就導(dǎo)致了本來3個字節(jié)才能完整定義一個方向鍵的行為,但是我只發(fā)過去一個字節(jié),所以終端并不知道我要干什么。所以沒有變化,當(dāng)下次觸發(fā)按鍵,才會把上一次的信息完整發(fā)過去,看起來就是按一下方向鍵有延遲。多字節(jié)的粘貼也是一個原理。解決辦法是將輸入緩沖區(qū)置為0,這樣就沒有緩沖,有多少發(fā)過去多少,這樣就不會有那種顯示的延遲問題了。

2、終端大小適應(yīng)。paramiko.channel會創(chuàng)建一個pty(偽終端),有個默認的大?。╳idth=80, height=24),所以登錄過去會發(fā)現(xiàn)能顯示的區(qū)域很小,并且是固定的。編輯vim的時候尤其痛苦。channel中有resize_pty方法,但是需要獲取到當(dāng)前終端的大小。經(jīng)查找,當(dāng)終端窗口發(fā)生變化時,系統(tǒng)會給前臺進程組發(fā)送SIGWINCH信號,也就是當(dāng)進程收到該信號時,獲取一下當(dāng)前size,然后再同步到pty中,那pty中的進程等于也感受到了窗口變化,也會收到SIGWINCH信號。

3、讀寫‘慢'設(shè)備(包括pipe,終端設(shè)備,網(wǎng)絡(luò)連接等)。讀時,數(shù)據(jù)不存在,需要等待;寫時,緩沖區(qū)滿或其他原因,需要等待。ssh通道屬于這一類的。本來進程因為網(wǎng)絡(luò)沒有通信,select調(diào)用為阻塞中的狀態(tài),但是當(dāng)終端窗口大小變化,接收到SIGWINCH信號被喚醒。此時select會出現(xiàn)異常,觸發(fā)系統(tǒng)中斷(4, 'Interrupted system call'),但是這種情況只會出現(xiàn)一次,當(dāng)重新調(diào)用select方法又會恢復(fù)正常。所以捕獲到select異常后重新進行select可以解決該問題。

以上這篇python獲取交互式ssh shell的方法就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 手把手教你Python抓取數(shù)據(jù)并可視化

    手把手教你Python抓取數(shù)據(jù)并可視化

    很多小伙伴在提到python數(shù)據(jù)可視化的時候第一反應(yīng)就是matplotlib庫,但實際上python還有很多很好用的數(shù)據(jù)可視化的庫,下面這篇文章主要給大家介紹了關(guān)于如何利用Python抓取數(shù)據(jù)并可視化的相關(guān)資料,需要的朋友可以參考下
    2022-05-05
  • 利用anaconda作為python的依賴庫管理方法

    利用anaconda作為python的依賴庫管理方法

    今天小編就為大家分享一篇利用anaconda作為python的依賴庫管理方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • Python快速轉(zhuǎn)換numpy數(shù)組中Nan和Inf的方法實例說明

    Python快速轉(zhuǎn)換numpy數(shù)組中Nan和Inf的方法實例說明

    今天小編就為大家分享一篇關(guān)于Python快速轉(zhuǎn)換numpy數(shù)組中Nan和Inf的方法實例說明,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • 使用Python從有道詞典網(wǎng)頁獲取單詞翻譯

    使用Python從有道詞典網(wǎng)頁獲取單詞翻譯

    這篇文章主要介紹了使用Python從有道詞典網(wǎng)頁獲取單詞翻譯的相關(guān)資料,需要的朋友可以參考下
    2016-07-07
  • Android模擬器無法啟動,報錯:Cannot set up guest memory ‘a(chǎn)ndroid_arm’ Invalid argument的解決方法

    Android模擬器無法啟動,報錯:Cannot set up guest memory ‘a(chǎn)ndroid_arm’ I

    這篇文章主要介紹了Android模擬器無法啟動,報錯:Cannot set up guest memory ‘a(chǎn)ndroid_arm’ Invalid argument的解決方法,通過模擬器ram設(shè)置的調(diào)整予以解決,需要的朋友可以參考下
    2016-07-07
  • Python在Console下顯示文本進度條的方法

    Python在Console下顯示文本進度條的方法

    Python是一門與php有點像的編輯語言了,下文來給各位在利用Python實現(xiàn)進度條了,對Python在Console下顯示文本進度條的方法相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧
    2016-02-02
  • Python通過調(diào)用有道翻譯api實現(xiàn)翻譯功能示例

    Python通過調(diào)用有道翻譯api實現(xiàn)翻譯功能示例

    這篇文章主要介紹了Python通過調(diào)用有道翻譯api實現(xiàn)翻譯功能,結(jié)合實例形式分析了基于Python實現(xiàn)的有道翻譯api調(diào)用相關(guān)操作技巧,需要的朋友可以參考下
    2018-07-07
  • Scrapy將數(shù)據(jù)保存到Excel和MySQL中的方法實現(xiàn)

    Scrapy將數(shù)據(jù)保存到Excel和MySQL中的方法實現(xiàn)

    本文主要介紹了Scrapy將數(shù)據(jù)保存到Excel和MySQL中的方法實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • web.py獲取上傳文件名的正確方法

    web.py獲取上傳文件名的正確方法

    這篇文章主要介紹了web.py獲取上傳文件名的正確方法,遇到這個問題的朋友可能會困惑半天,使用本文的正確方法就可以解決這個問題了,需要的朋友可以參考下
    2014-08-08
  • 詳解Django定時任務(wù)模塊設(shè)計與實踐

    詳解Django定時任務(wù)模塊設(shè)計與實踐

    這篇文章主要介紹了詳解Django定時任務(wù)模塊設(shè)計與實踐,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07

最新評論

托克托县| 朝阳区| 琼海市| 临泽县| 北辰区| 璧山县| 资源县| 云龙县| 临高县| 水城县| 修文县| 横山县| 松滋市| 沂水县| 南安市| 克山县| 五峰| 安西县| 丹寨县| 合阳县| 咸宁市| 社会| 扎赉特旗| 大同市| 九龙坡区| 博湖县| 舞阳县| 宜兰县| 平阳县| 四川省| 昌宁县| 玛纳斯县| 鄂伦春自治旗| 油尖旺区| 长寿区| 泉州市| 汉川市| 得荣县| 哈巴河县| 芦山县| 奈曼旗|