有任何方法可以通过SSH连接打开和读取文件
there is any way to open and read a file over a SSH connection?
我可以访问一些有大量数据的服务器。我无法在电脑上复制全部数据。
我无法在服务器上编译我想要的程序,因为服务器没有我需要的所有库。
我不认为服务器管理员会很高兴看到我来并要求他为我安装一些libs…
所以,我想知道是否有一种方法可以打开一个文件,比如
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(进行HTTPS访问(如果远程计算机为你的文件提供了HTTPS访问((或者反过来,使用一些HTTP-HTTPS服务器库,如libonion(
你可以(但首先要征得许可!(通过OpenSSL或libgnutls 使用一些TLS连接(例如,在远程超级计算机上手动启动类似服务器的程序(
最后,您应该考虑在远程计算机上安装(即礼貌地要求在远程超级计算机上安装(或使用一些数据库软件(如PostgreSQL或MariaDB或Redis或MongoDB服务器(,使您的程序成为数据库客户端应用程序。。。
顺便说一句,如果你随机访问几十个TB大小的文件(每次运行读取文件中的几千字节(,或者访问一百万个文件,其中给定的运行通过顺序读取只访问其中的十几个文件,每个文件的大小都合理(几兆字节(,情况可能会有所不同。换句话说,DNA数据、视频电影、HTML文档、源代码。。。都是不同的情况!
好吧,你的问题的答案是no,正如已经说过的几次(除非你考虑自己实现ssh这超出了理智的范围(。
但是,当你描述你的真实问题时,它可能只是问错了问题,所以——寻找替代方案:
备选方案1
将要静态使用的库链接到二进制文件。假设您想静态链接libfoo:
-
确保在库搜索路径中有
libfoo.a
(库的对象存档(。通常,您的发行版提供的库的开发包已经包含了它,如果没有,请自己编译该库,并提供创建静态库的选项 -
假设使用GNU工具链,使用以下标志构建程序:
-Wl,-Bstatic -lfoo -Wl,-Bdynamic
(而不仅仅是-lfoo
(
备选方案2
像往常一样创建二进制文件(与动态库链接(,并将该库(libfoo.so
(放在服务器上的~/lib
中。然后用LD_LIBRARY_PATH=~/lib ./a.out
在那里运行二进制文件。
您可以通过SSH连接将部分文件复制到您的计算机:
- 使用
dd
命令将源文件的一部分复制到临时文件 - 使用
scp
或rsync
将临时文件复制到本地邮箱
如果需要多次执行,可以创建一个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
创建一个管道,然后使用fork
和exec*
创建ssh
进程,安装管道的写端作为其stdout,并使用fdopen
在父进程中管道的读端创建FILE *
流。这样,就可以准确地控制传递给进程的参数:至少在本地,您没有运行shell命令。
您不能直接(1(使用fopen((或ifstream::open通过ssh打开文件。但是您可以利用现有的ssh
二进制文件。只需让您的程序从stdin读取,然后通过ssh:将文件传输到stdin
ssh that_server cat /path/to/largefile | ./yourprogram
(1( 好吧,如果您使用sshfs装载远程系统,您可以通过ssh访问这些文件,就好像它们是本地的一样。
- 使用新行和不使用新行读取文件
- 读取文件并输入到矢量中
- 读取文件的最后一行并输入到链接列表时出错
- 为什么在读取文件大小时文件IO速度会发生变化
- 读取文件时运行时的未知行为
- 如何逐行读取文件,每行中的内容都用空格分隔并将其写入新文件中
- 读取文件中所有可能的十六进制 16 字节序列并打印每个序列
- C++ 读取文件读取文件不正确
- 读取文件并将其存储在unordered_map中时出现问题
- 读取文件时无法使用 OpenMP 获得加速
- 使用istringstearm和get行缓慢读取文件
- 如何继续读取不同功能中的文件,而不是从头开始再次读取文件?
- 读取文件时引发异常
- 从标准输入读取文件后读取用户输入
- 在读取文件后重置句柄
- 如何在C++编译时读取文件?
- std::ifstream 在读取文件中最后一项时设置 eofbit,但仅在读取数值类型时发生
- 读取文件在第二次调用时返回INVALID_HANDLE
- 通过指针读取文件
- 逐行读取文件,并将数据插入变量和数组中