日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

用python实现远程复制 (scp + expect )

發布時間:2023/12/2 python 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用python实现远程复制 (scp + expect ) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

scp 功能很強大,但需要人工輸入 password, 當然可以通過把 公鑰保存在遠程主機的 ~/.ssh 目錄中,而后就不用輸入password,但這需要配置.

用 sshpass 可能在命令輸入 password, 但 需要用 “sudo apt-get install sshpass” 安裝

如果不想用上面兩種方法,可以用 expect 編寫腳本可以幫助我們自動交互

雖然 python 也提供?pexpect ?模塊,但既然 expect 很簡單,為何不直接用 os.system() 去執行呢?

下面是我編寫的類,實現了遠程復制?

[html] view plaincopyprint?
  • class?RemoteShell:??
  • ??
  • ????def?__init__(self,?host,?user,?pwd):??
  • ????????self.host?=?host??
  • ????????self.user??=?user??
  • ????????self.pwd??=?pwd??
  • ??
  • ??
  • ????def?put(self,?local_path,?remote_path):??
  • scp_put?=?'''??
  • spawn?scp?%s?%s@%s:%s??
  • expect?"(yes/no)?"?{??
  • send?"yes\r"??
  • expect?"password:"??
  • send?"%s\r"??
  • }?"password:"?{send?"%s\r"}??
  • expect?eof??
  • exit'''??
  • ????????os.system("echo?'%s'?>?scp_put.cmd"?%?(scp_put?%?(os.path.expanduser(local_path),?self.user,?self.host,?remote_path,?self.pwd,?self.pwd)))??
  • ????????os.system('expect?scp_put.cmd')??
  • ????????os.system('rm?scp_put.cmd')??
  • class RemoteShell:def __init__(self, host, user, pwd):self.host = hostself.user = userself.pwd = pwddef put(self, local_path, remote_path): scp_put = ''' spawn scp %s %s@%s:%s expect "(yes/no)?" { send "yes\r" expect "password:" send "%s\r" } "password:" {send "%s\r"} expect eof exit'''os.system("echo '%s' > scp_put.cmd" % (scp_put % (os.path.expanduser(local_path), self.user, self.host, remote_path, self.pwd, self.pwd)))os.system('expect scp_put.cmd')os.system('rm scp_put.cmd')
    但發現每次文件都沒有復制完,我想看expect 究竟做了什么事情,還好 expect 提供 -d 參數給出更多的信息。

    最后發現是被復制文件太大,expect 超時退出了

    在腳本前加入 “set timeout -1" 就OK了


    [html] view plaincopyprint?
  • scp_put?=?'''??
  • set?timeout?-1??
  • spawn?scp?%s?%s@%s:%s??
  • expect?"(yes/no)?"?{??
  • send?"yes\r"??
  • expect?"password:"??
  • send?"%s\r"??
  • }?"password:"?{send?"%s\r"}??
  • expect?eof??
  • exit'''??
  • scp_put = ''' set timeout -1 spawn scp %s %s@%s:%s expect "(yes/no)?" { send "yes\r" expect "password:" send "%s\r" } "password:" {send "%s\r"} expect eof exit'''
    總結

    1) expect 每一條語句都是順序執行

    [html] view plaincopyprint?
  • ??
  • </pre>?因為scp 可能先返回 (yes/no)? 再 返回 password:, 也可能直接返回password:, 考慮順序關系,上面語句的層次關系其實如下: <div class="dp-highlighter bg_html"><div class="bar"><div class="tools"><strong>[html]</strong> <a target=_blank title="view plain" class="ViewSource" href="http://blog.csdn.net/span76/article/details/11575231#">view plain</a><a target=_blank title="copy" class="CopyToClipboard" href="http://blog.csdn.net/span76/article/details/11575231#">copy</a><a target=_blank title="print" class="PrintSource" href="http://blog.csdn.net/span76/article/details/11575231#">print</a><a target=_blank title="?" class="About" href="http://blog.csdn.net/span76/article/details/11575231#">?</a></div></div><ol class="dp-xml"><li class="alt"><span><span>expect?"(yes/no)?"?{???send?"yes\r"??</span></span></li><li><span>???????????????????????expect?"password:"??</span></li><li class="alt"><span>???????????????????????send?"%s\r"??</span></li><li><span>????????????????????}???</span></li><li class="alt"><span>???????"password:"?{send?"%s\r"}??</span></li></ol></div><pre class="html" style="display: none;" name="code">expect "(yes/no)?" { send "yes\r"expect "password:"send "%s\r"} "password:" {send "%s\r"}
    2) 每當 spawn 的程序有輸出的時候的,expect都會去匹配, 如果匹配不上,就等下次有輸出,再次執行當前的 expect, 直到超時 (我用 expect -d 去追蹤,得到的結論);當然可以設置沒有超時 "set timeout -1"


    3) 如果 ?expect 退出, 被它 spawn 的程序會被 kill 掉


    4) spawn 結束的時候,它向標準輸出的的 eof 會被 expect 檢測到,正好作為 expect 腳本退出的時機。

    對于 scp 可以先檢測 100%,因為 scp 會輸出復制進度,再檢測 eof

    [html] view plaincopyprint?
  • expect?"100%%"??
  • expect?eof??
  • expect "100%%" expect eof


    5) expect 是部分匹配,所以不要擔心自己不知道程序的完整輸出

    版權聲明:本文為博主原創文章,未經博主允許不得轉載。

    總結

    以上是生活随笔為你收集整理的用python实现远程复制 (scp + expect )的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。