簡體   English   中英

有什么方法可以通過SSH連接打開和讀取文件?

[英]there is any way to open and read a file over a SSH connection?

我可以訪問一些數據很多的服務器。 我無法在計算機上復制全部數據。

我無法在服務器上編譯我想要的程序,因為服務器沒有我需要的所有庫。

我不認為服務器管理員會很高興看到我過來並要求他為我安裝一些庫...

因此,我嘗試找出是否有一種方法可以像這樣打開文件,

FILE *fopen(const char *filename, const char *mode);

要么

void std::ifstream::open(const char* filename,  ios_base::openmode mode = ios_base::in);

但通過SSH連接。 然后像讀取普通程序一樣讀取文件。

計算機和服務器都在運行linux

我假設您正在使用Linux筆記本電腦,並且遠程計算機是一些超級計算機。

首要的非技術建議:首先征得許可,以遠程訪問數據。 在某些工作場所,即使在技術上可行,您也不允許這樣做。

您可以為此目的使用libssh ,但是您需要一些編碼並閱讀其文檔。

您可以考慮使用某些FUSE文件系統(在筆記本電腦上),例如某些sshfs 這樣您就可以訪問一些超級計算機文件,例如/sshfilesystem/foo.bar )。 這可能是最慢的解決方案,並且可能不是非常可靠的解決方案。 我真的不推薦它。

您可以要求使用NFS掛載的權限。

也許您可能會考慮使用某些HTTP / HTTPS客戶端庫(例如libcurl) (或者反過來使用某些HTTP / HTTPS服務器庫(例如libonion ))來進行HTTPS訪問(如果遠程計算機上有您的文件)。

你可能(但請允許第一!)使用一些TLS連接(例如,手動啟動像遠程超級計算機程序的服務器)也許直通OpenSSL的libgnutls

最后,您應該考慮在遠程計算機上安裝(即禮貌地要求在遠程超級計算機上進行安裝)或使用某些數據庫軟件(例如PostgreSQLMariaDBRedisMongoDB服務器),並使您的程序成為數據庫客戶端應用程序。 。

順便說一句,如果您以隨機訪問方式訪問數十個TB級文件(每個運行時讀取其中的幾千字節),或者訪問一百萬個文件,則可能有所不同,其中給定運行時只能按順序讀取其中的十幾個文件,每個文件大小合理(幾兆字節)。 換句話說,DNA數據,視頻電影,HTML文檔,源代碼……都是不同的情況!

好吧,您的問題的答案是“ 否” ,正如已經多次說明的那樣(除非您考慮自己實施ssh ,這超出了理智的范圍)。

但是,正如您還描述您的實際問題時,可能只是問錯了問題,所以-尋找替代方案:

選擇1

將要靜態使用的庫鏈接到二進制文件。 假設您要靜態鏈接libfoo

  • 確保在庫搜索路徑中有libfoo.a (庫的對象檔案庫)。 通常,您的發行版提供的庫的開發包中已經包含了該庫,如果沒有,請使用選項自行編譯該庫以啟用靜態庫的創建

  • 假設使用GNU工具鏈,請使用以下標志構建程序: -Wl,-Bstatic -lfoo -Wl,-Bdynamic (而不是-lfoo

選擇2

照常創建二進制文件(與動態庫鏈接),然后將該庫( libfoo.so )放在服務器上的~/lib 然后使用LD_LIBRARY_PATH=~/lib ./a.out運行二進制文件。

您可以通過SSH連接將文件的一部分復制到計算機上:

  • 使用dd命令將部分源文件復制到臨時文件
  • 使用scprsync將臨時文件復制到本地盒中

如果需要多次執行此操作,則可以創建一個Shell腳本來自動執行此操作。

可以在ssh命令上使用popen代替在路徑上使用fopen (不要忘記,從popen獲得的FILE *流是用pclose而不是fclose關閉的)。

您可以通過編寫包裝popen的函數來簡化接口。 該函數僅接受遠程文件名,然后生成ssh命令以獲取該文件,並正確轉義所有內容,例如文件名中的空格,shell元字符和諸如此類。

FILE *stream = popen("ssh user@host cat /path/to/remote/file", "r");

if (stream != 0) {
   /* ... */
  pclose(stream);
}

popen有一些缺點,因為它處理shell命令。 由於ssh的參數也是在遠程端處理的shell命令,因此會引起雙重轉義的問題:將命令作為shell命令傳遞。

為了做得更健壯,可以使用pipe創建一個管道,然后forkexec* ssh進程,將管道的寫端安裝為stdout,然后使用fdopen在管道的讀取端創建FILE *流在父進程中。 這樣,可以精確控制傳遞給進程的參數:至少在本地,您沒有運行shell命令。

您不能直接(1)使用fopen()或ifstream :: open通過ssh打開文件。 但是您可以利用現有的ssh二進制文件。 只需讓您的程序從stdin中讀取,然后通過ssh將文件通過管道傳遞到它:

ssh that_server cat /path/to/largefile | ./yourprogram

(1)好吧,如果使用sshfs掛載遠程系統,則可以通過ssh訪問文件,就好像它們是本地文件一樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM