今天收到了研发同学的一个工单,内容大体是:需要将文件拷贝到服务器上去,请求帮助安装 scp 程序。
我尝试了对那台服务器执行 scp 命令,结果是 -bash: scp: command not found
,但是 ssh 是正常可以用的。这种情况下应该是 openssh-clients 被删掉了。
但是!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 拷贝到服务器上去。
1 |
cat ~/.ssh/id_rsa.pub | ssh root@myserver.com "cat - >> .ssh/authorized_keys" |
将一个文件传输到服务器:
1 |
cat myfile | ssh root@myserver.com "cat - > /tmp/myfile" |
上面这个命令的原理就是,将文件内容输入到 stdout 中,用管道和 ssh 连接起来,然后这个 stdout 就成了远程命令的 stdin。
要拷贝整个文件夹呢?没有问题:
1 |
tar c . | ssh root@myserver.com "tar xv" |
如果是像日志这种压缩性能很高的文件,可以考虑压缩之后再传输,远程那边从 stdin 解压缩。而且直接将输入和输出通过管道连接起来,压缩中间生成的文件丝毫不会占用空间呢!
1 |
tar cz . | ssh sit.takachiho "tar xzv" |
如果要指定远程的目标文件夹,可以使用 tar 的 C 参数来指定,比如远程解压缩到 /tmp
下面:
1 |
tar cz . | ssh sit.takachiho "tar xzvC /tmp" |
要注意像图片、视频这种二进制文件,本身就是经过压缩之后的了,如果再使用 tar z 来压缩一遍的话,不会节省多少传输体积,反而会白白耗费 CPU。
实用技巧:如果每天备份 MySQL 到另一台机器,但是不占用本机空间?Crontab 的脚本这么写:
1 |
mysqldump --single-transaction -u backuper mydb | ssh root@backup.myserver.com "cat - > /var/mysql_back.sql" |
假如一台机器A在一个网络环境,另一个机器B在另一个网络环境,他们之间不互通。但是你的电脑(或堡垒机)能同时用 ssh 登陆两台机器,那么怎么把 Server A 的文件拷贝到 Server B?
用两个 ssh!
1 |
ssh root@serverA "cat file" | ssh root@serverB "cat - > /tmp/file" |
理解 ssh 能连接 stdin 和 stdout 了,就有无限的可能了!而且你可以将脚本都放在本地,不用还得本地放一些,远程的机器放一些通过 ssh 来执行。
哦对了,ssh 是一个加密的协议,所以在传输的过程中会看到 CPU 使用上涨,因为这是在加密和(远程服务器)解密。用的时候需要考虑到这个。scp 命令是基于 ssh 的,所以会有一样的问题。
nc 基于 tcp 明文传输的,如果不需要加密,传输内容比较多,可以考虑用这个。
在 Server 端执行 nc 监听端口,将输入到 nc 的内容输出到一个文件中。
1 |
nc -l -p 1234 -q 1 > something.zip < /dev/null |
然后在 Client 端将要发送的文件输入到服务器的这个端口中:
1 |
cat something.zip | netcat server.ip.here 1234 |
这个独门绝技是 @mrluanma 教我的。
http://gholk.github.io/linux-easy-shell-send-file.html#scat
scp 可以傳檔案但不能處理標準輸入輸出, ssh cat 又太長太麻煩, 我就寫了個 scat 腳本來處理標準輸入輸出。
很酷,不过我现在已经能很快写 ssh cat 了,已经熟悉了,哈哈
这个玩法太牛逼了、
雕虫小技,哈哈
Pingback: 实时上传数据备份文件到S3 | 卡瓦邦噶!