用 ssh 传输文件

今天收到了研发同学的一个工单,内容大体是:需要将文件拷贝到服务器上去,请求帮助安装 scp 程序。

我尝试了对那台服务器执行 scp 命令,结果是 -bash: scp: command not found,但是 ssh 是正常可以用的。这种情况下应该是 openssh-clients 被删掉了。

但是!scp 命令是基于 ssh 协议的,既然可以用 ssh ,还要什么 scp 呢!

我们可以直接用 ssh 就可以传输文件,学会了之后,发现它比 scp 还好用,scp 的 path 写起来比较蛋疼。

首先很多人忽略的一个事实是,ssh 可以直接输入命令对远程主机执行,比如 ssh root@myserver.com "cat access.log" ,就可以直接 cat 出远程文件的 log 内容。ssh 会将远程命令的 stdout 和本地的 stdout 连接起来。可以用这样的命令来看实时的日志: ssh root@myserver.com "tail -f access.log"。这样就可以在本地执行一条命令就可以了,方便脚本化或记录到 本地 history。

既然 ssh 可以将 stdout 连接起来,那么自然也可以将 stdin 连接起来!比如用这个命令将 ssh key 拷贝到服务器上去。

将一个文件传输到服务器:

上面这个命令的原理就是,将文件内容输入到 stdout 中,用管道和 ssh 连接起来,然后这个 stdout 就成了远程命令的 stdin。

要拷贝整个文件夹呢?没有问题:

如果是像日志这种压缩性能很高的文件,可以考虑压缩之后再传输,远程那边从 stdin 解压缩。而且直接将输入和输出通过管道连接起来,压缩中间生成的文件丝毫不会占用空间呢!

如果要指定远程的目标文件夹,可以使用 tar 的 C 参数来指定,比如远程解压缩到 /tmp 下面:

要注意像图片、视频这种二进制文件,本身就是经过压缩之后的了,如果再使用 tar z 来压缩一遍的话,不会节省多少传输体积,反而会白白耗费 CPU。

实用技巧:如果每天备份 MySQL 到另一台机器,但是不占用本机空间?Crontab 的脚本这么写:

假如一台机器A在一个网络环境,另一个机器B在另一个网络环境,他们之间不互通。但是你的电脑(或堡垒机)能同时用 ssh 登陆两台机器,那么怎么把 Server A 的文件拷贝到  Server B?

用两个 ssh!

理解 ssh 能连接 stdin 和 stdout 了,就有无限的可能了!而且你可以将脚本都放在本地,不用还得本地放一些,远程的机器放一些通过 ssh 来执行。

哦对了,ssh 是一个加密的协议,所以在传输的过程中会看到 CPU 使用上涨,因为这是在加密和(远程服务器)解密。用的时候需要考虑到这个。scp 命令是基于 ssh 的,所以会有一样的问题。

nc 基于 tcp 明文传输的,如果不需要加密,传输内容比较多,可以考虑用这个。

在 Server 端执行 nc 监听端口,将输入到 nc 的内容输出到一个文件中。

然后在 Client 端将要发送的文件输入到服务器的这个端口中:

 

这个独门绝技是 @mrluanma 教我的。

用 ssh 传输文件”已经有4条评论

Leave a comment

电子邮件地址不会被公开。 必填项已用*标注