2

Ssh传输文件

 2 years ago
source link: https://3mile.github.io/archives/2020/0408094222/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Ssh传输文件

2020-04-08

发布在 Linux

A beautiful sunrise

今天需要上传文件到服务器,但是文件数量巨大且文件容量极小。如果用传统的SCP速度极慢,所以准备用scp传输.gz压缩文件到服务器,然后在服务器上解压。

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

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

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

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

cat ~/.ssh/id_rsa.pub \| ssh [email protected] "cat - >> .ssh/authorized_keys"

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

cat myfile \| ssh [email protected] "cat - > /tmp/myfile"

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

img

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

tar c . \| ssh [email protected] "tar xv"

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

tar cz . \| ssh sit.takachiho "tar xzv"

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

tar cz . \| ssh sit.takachiho "tar xzvC /tmp"

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

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

mysqldump --single-transaction -u backuper mydb \| ssh [email protected] "cat - > /var/mysql_back.sql"

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

img

用两个 ssh!

ssh root@serverA "cat file" \| ssh root@serverB "cat - > /tmp/file"

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

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

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

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

nc -l -p 1234 -q 1 > something.zip < /dev/null

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

cat something.zip \| netcat server.ip.here 1234

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK