回顾我们的老朋友 scp
说到ssh
,大家一定不陌生,毕竟老板叫你进去去服务器看看日志有啥报错总归得敲下面的命令:
ssh user@ip
今天遇到了一个比较烦人的情况,我的pc是可以连上服务器A和服务器B。
但是服务器A和B之间网络并不通。如下图:

前端老哥走 CI/CD 自动 build 好的 目标文件 在 S1服务器 上面,我需要把这些目标文件部署在S2上面,并且让nginx去host这些文件。很显然,从上面的图看出,我并不能直接做以下的操作。
ssh root@s1
scp /usr/share/auto/fontend/dist/* root@s2:/usr/share/nginx/host/
其实也很简单,我在我的pc上面,用两次scp
,先把S1中的需要传的文件先传到PC本地,然后再传去S2。
scp root@s1:/usr/share/auto/fontend/dist/* .
scp ./* root@s2:/usr/share/nginx/host/
rm -rf *
嗯哼,问题似乎已经解决了。但是我需要去rm
掉我PC中的中转站文件呢!这似乎有点不够优雅。作为一个新时代的弄潮儿,我们需要更加cool的操作去完成这个事情!
ssh可以远程输入命令
ssh不光可以远程到别的服务器上,他也可以直接输入命令!
ssh root@s1 'pwd'
上面这个命令就是远程到s1服务器,并且输入pwd命令,并且把程序的输出接入到本地的stdout中。
也就是说,其实我根本不需要用scp命令!我从远程的服务器上下载一个文件到本地只需要借助重定向就行!
ssh root@s1 'cat file1' > file1
那么上传一个文件呢?我们需要借助管道符!
使用飘逸的管道符传单个文件
我们可以借助管道符,把命令的stdout接入下一个命令的stdin,ssh
命令是可以支持接入stdin的。
cat file1 | ssh root@s1 'cat - > file1'
这里的流程是 pc: stdout -> pc: ssh: stdin -> s1: stdin -> s1: stdout -> pc:ssh: stdout
这样一来不需要scp,文件就从本地到服务器了。
更进一步,传多文件?
我们又需要另外借助一个好兄弟 tar
,我们先把本地/远程的多个文件先打成tar包,然后再在远程/本地再进行解压,这不就完成了多文件传输了吗。
下面这个例子会将s1服务器中/root/files
中的所有文件传输到本地的当前目录下,并且我们可以看到tar
中有-z
,这代表他打包的同时会压缩,-C
代表会切换到/root/files
目录下再进行打包,如果没有加-C
,后果不堪设想哈(不建议随意尝试)
玩过英雄联盟亚索的人应该知道,很多时候你花里胡哨E几次,你就超鬼了
ssh root@s1 'tar -czf - -C /root/files .' | tar -xzv
逆向思维一下,本地传去远程呢?那就在本地去打包,远程的去解压。
tar -cz . | ssh root@s1 'tar -xz -C /root/files'
来一套Combo
回到我们一开始提出的问题,如果S1服务器和S2网络不通,那如何优雅的从S1传文件多个文件到S2呢?
不如让我们把两个ssh
命令用管道符连接起来吧!
ssh root@s1 'tar -czf - -C /usr/share/auto/fontend/dist .' | ssh root@s1 'tar -xz -C /usr/share/nginx/host'
这样一来,我们就把s1中前端老哥编译好的文件全部复制到s2中了!