2009-10-20 65 views
23

我試圖從服務器上使用ssh從python讀取文件。我使用paramiko來連接。我可以連接到服務器並運行一個像'cat filename'這樣的命令並從服務器獲取數據,但是我嘗試讀取的一些文件大小大約爲1 GB或更多。使用python從ssh讀取服務器上的文件

我該如何使用python逐行讀取服務器上的文件?

附加信息:什麼是經常要做的就是運行一個「貓文件名」命令,並把結果保存在一個變量和工作過這一點。但由於這裏的文件相當大,我正在尋找一種逐行讀取文件的方式。

編輯:我可以讀取一組數據,並將其分割成線,但問題是,在緩衝區接收到的數據並不總是包含完整的生產線。例如,如果緩衝區有300行,最後一行可能只是服務器上一行的一半,下一半將在下次調用服務器時被取回。我想完整線

編輯2:我可以在一定範圍內使用的命令行打印在一個文件中。像打印前100行,然後下100個等等?這樣緩衝區將始終包含完整的行。

+2

你能不能SFTP文件? – 2009-10-20 20:11:02

+0

那麼你是否逐行閱讀,因爲你不想把數據放在shell腳本變量中?變量被設置在哪一端?本地結束?在閱讀遠端的下一頁之前在近端處理一條線是否重要? – 2009-10-20 20:22:29

回答

44

Paramiko'sSFTPClient類可以讓你得到一個類文件對象的Python化的方式從遠程文件讀取數據。

假設你有一個開放SSHClient

+5

+1,比貓好得多(對於我喜歡貓的所有人來說 - )。 – 2009-10-21 02:28:32

+0

在我的情況下,文件內容是一個單行中的json數據(我想要做json.load並存儲在變量中)。這個文件的大小是〜200MB。當我嘗試讀取remote_file中的行時,它永遠不會回來,它只是卡住了。任何人都可以幫助我嗎? – 2017-08-23 10:08:13

4

你的「逐行」的意思 - 有大量的網絡主機之間的數據緩衝區,和他們都不是面向行的。

所以,你可以讀一組數據,那麼它在近端分割成線。或者你可以讓一個進程在遠端讀取一堆數據,分解並逐行格式化併發送給你。

scp process_standard_input.py otherhost 
ssh otherhost python process_standard_input.py somefile | do_process_locally 

我只關心的唯一區別是通過有限的網絡管道減少數據量。在你的情況下,它可能,也可能不重要。

有沒有錯,一般使用cat通過SSH管道移動千兆字節的數據。

3
#!/usr/bin/env python 
import paramiko 
import select 
client = paramiko.SSHClient() 
client.load_system_host_keys() 
client.connect('yourhost.com') 
transport = client.get_transport() 
channel = transport.open_session() 
channel.exec_command("cat /path/to/your/file") 
while True: 
    rl, wl, xl = select.select([channel],[],[],0.0) 
    if len(rl) > 0: 
     # Must be stdout 
     print channel.recv(1024) 
+0

paramiko的好例子,但又突出了這種任務的非線性導向性質。 – 2009-10-20 20:20:21

+0

只要繼續閱讀它,直到獲得換行符或其他行終止字符。 – g33kz0r 2009-10-20 21:57:15

9

下面是一個擴展@Matt Good's answer

from contextlib  import closing 
from fabric.network import connect 

with closing(connect(user, host, port)) as ssh, \ 
    closing(ssh.open_sftp()) as sftp, \ 
    closing(sftp.open('remote_filename')) as file: 
    for line in file: 
     process(line) 
+0

我從來沒有見過contextlib.closing。所以這可以讓你用close()方法將任何東西變成類似於Context Manager的東西,儘管它可能沒有\ _ \ _和\ _ \ _ exit \ _ \ _? – hughdbrown 2009-10-21 04:14:33

+0

@hughbrown:是的。任何帶有'.close()'方法的對象都可以。 'closing'的實現是微不足道的,參見http://svn.python.org/view/python/trunk/Lib/contextlib.py?view=markup – jfs 2009-10-21 20:26:51

+0

其實'sftp.open('remote_filename')與f :'也可以工作 – taras 2015-10-13 20:54:32

相關問題