乐趣区

关于linux:SHell-的远程传递

SHell 的近程传递

0x00

家喻户晓,有个命令叫 rsync

不晓得?那你可能听过 scp,都不晓得也没事,正好。

个别,你想往远处(10.60.111.124)用指定用户(heihei)的指定目录($HOME/yoyo)里,传过来一个文件(oho.iex),这个文件就在当前目录。

(对本机来说也就是上传本地文件到远端某目录)

那么个别的做法就是这样:

rsync -avz -- oho.iex heihei@10.60.111.124:yoyo

这样的话能做到以下几件事:

  • 完全相同的文件如果曾经在目标目录存在,这个文件就不会被传输;文件名雷同文件内容不同则会笼罩。
  • 选项 a 使得这个文件的元数据信息(创立工夫、批改工夫、文件归属等这些并不存在文件内容里的信息)失去保留;选项 z 会开启压缩即上传前先压缩过了网络后再主动解压,这样就能省流;选项 v 则是显示传输过程,有没有都不影响传输终局。

因为要上传的文件就在当前目录,所以 -- 前面的 oho.iex 连相对路径的 ./ 也不必写,更不须要写绝对路径。又因为文件夹正好在这个用户的 $HOME 目录下,所以冒号 : 前面也不必写绝对路径。事实上,如果只有冒号 : 前面空着,文件就会被上传到所应用用户 heihei 的家目录。(但如果你冒号都没写,这个工具就认为你只是把文件从本地传到本地,就会当前目录建设一个 heihei@10.60.111.124 文件夹而后把文件复制进去。。。)

从远端(10.60.111.128)通过指定用户(haha)把指定文件(/etc/profile.d/miaomiao.sh)拉到本地指定目录(当前目录 .),也是相似的。

(对本机来说也就是下载指定文件到本地指定目录)

你能够这样写:

rsync -avz -- haha@10.60.111.128:/etc/profile.d/miaomiao.sh .

这个应该不必解说了吧。。。

然而,还有个问题:这个软件须要对面也装了才行。而且还得不能出错。

0x01

如果只关怀文件内容的传递,只有你们两边都有 SSH,那么大能够像这样做:

拉取(对本机来说算下载)

ssh haha@10.60.111.128 -- 'cat /etc/profile.d/miaomiao.sh' > miaomiao.sh

推送(对本机来说算上传)

cat oho.iex | ssh heihei@10.60.111.124 -- 'cat > yoyo/oho.iex'

当然,还能够自行选定压缩工具(须要两边都安)。这里以 xz 举例:

拉取(对本机来说算下载)

ssh haha@10.60.111.128 -- 'cat /etc/profile.d/miaomiao.sh | xz -T0 --best' | xz -dc > miaomiao.sh

推送(对本机来说算上传)

(cat oho.iex | xz -T0 --best) | ssh heihei@10.60.111.124 -- 'cat | xz -dc > yoyo/oho.iex'

另外,当初不是有很多玩容器化的吗,docker 间接把 Go 这个语言带起来了。它的镜像反对导出 save 为文件和从文件和加载 load

个别的做法就是远端导出一个文件起个名字叫 啥啥.tar(导出的确实是 Tar 格局不论你给它文件名啥扩展名)而后挪到另一台上再导入。

当初咱们能够让它中途压缩,并且全程管道,不必专门学生成文件,不留多余的货色。

(这也多亏 docker 命令反对从规范输出加载镜像或从规范输入写出文件)

(这里的劳模镜像就用 docker.io/trinodb/trino 了。这个工作次要是用能连互联网的机器往不通互联网的机器传送镜像。)

## 远端镜像来本机:ssh haha@10.60.111.128 -- 'docker save docker.io/trinodb/trino | xz -T0 --best' | xz -dc | docker load
## 本机镜像到远端:docker save docker.io/trinodb/trino | xz -T0 --best | ssh haha@10.60.111.128 -- 'xz -dc | docker load'

## 甚至能够从这个远端间接送到那个远端!啊对!一般文件当然也能够这么玩儿!ssh haha@10.60.111.128 -- 'docker save docker.io/trinodb/trino | xz -T0 --best' | ssh heihei@10.60.111.124 -- 'xz -dc | docker load'

0x02

不过,ssh 是要明码的(基于 SSH 协定的工具都要(如 rsync 就是一个))。而有的时候其实不便于输明码。怎么办呢?

能够用 sshpass

(查了一下,这应该是个用 C 写的开源工具,不过貌似也有 PY 版本。。。无所谓,命令就能安,这里也有各种零碎的包。)

用法很简略:把下面的 ssh 换成 sshpass -p $xx -- ssh 就好了,其中变量 xx 曾经存入了对应节点对应用户的明码。

几个示例:

## 镜像远到本
sshpass -p $hahapassword -- ssh haha@10.60.111.128 -- 'docker save docker.io/trinodb/trino | xz -T0 --best' | xz -dc | docker load
## 文件远到远
sshpass -p $hahapassword -- ssh haha@10.60.111.128 -- 'cat /etc/profile.d/miaomiao.sh | xz -T0 --best' | sshpass -p $heiheipassword -- ssh heihei@10.60.111.124 -- 'cat | xz -dc > /etc/profile.d/miaomiao.sh'
## rsync 也能用 sshpass
sshpass -p $heiheipassword -- rsync -avz -- oho.iex heihei@10.60.111.124:yoyo

0x03

然而 rsync 还能一下传一个文件夹呢!

的确,下面这种最原始的伎俩只是传单个文件而已。要传文件夹的话,大能够先打包成 Tar 格局的文件,而后再传单个文件就好:

(用 SSH 协定的时候如果删掉指定的远端登录用户名和 @ 的话就等于用本机正在用的以后用户登录,这须要远端有雷同名称的用户并且你还晓得明码。)

## 远到本 当前目录
sshpass -p $xx -- ssh 10.20.202.233 -- 'tar cf - /etc/profile.d' | tar -x 
## 远到本 指定目录中途有压缩
sshpass -p $xx -- ssh 10.20.202.233 -- 'tar cf - /etc/profile.d | xz -T0 --best' | xz -dc | tar -x -C $HOME/documents
## 本到远 齐全同上的口头
tar cf - /etc/profile.d | xz -T0 --best | sshpass -p $xx -- ssh 10.20.202.233 -- 'xz -dc | tar -x -C $HOME/documents'
## 远到远 齐全同上的口头
sshpass -p $xx -- ssh 10.20.202.233 -- 'tar cf - /etc/profile.d | xz -T0 --best' | sshpass -p $xxx -- ssh 10.20.203.244 -- 'xz -dc | tar -x -C $HOME/documents'

其实只有能变成 Tar 包,剩下的就跟镜像的本义齐全一样了。

0x04

还能够批量搞事件。

比方你在本地某个目录,你想把外面所有文件名 .docx 结尾的文件传输给指定远端目录的特定目录里。

首先要手动建设目录:

sshpass -p $xx -- ssh haha@10.20.103.237 -- mkdir -p to_kiki

而后这样就能传了:

ls *.docx | 
    xargs -i -P0 -- bash -c "cat {} | sshpass -p $xx -- ssh haha@10.20.103.237 --'cat > to_kiki/{}'"

当然,批量拉取也是能够的(起源文件夹必定曾经是有的所以不再建设了):

sshpass -p $xx -- ssh haha@10.20.103.237 -- ls kiki | 
    xargs -i -P0 -- bash -c "sshpass -p $xx -- ssh haha@10.20.103.237 --'cat kiki/{}'> {}"

思路就是拼接命令,交给 xargs 批量执行。

这些示例没开压缩,需要的话本人触类旁通。其实没必要,只有货色不太大。

另外,也能够不必 xz 这个命令来压缩,也能够用 zstd,后者仿佛更适宜于这种场景。(原本用 .tar.xz 存安装包的 Arch 团队通过测试后改用这个压缩算法(级别是 18),速度大幅晋升同时压缩率则只是差了微不足道一点点。)

0x05

还能够这么着:

sshpass -p $xx -- ssh haha@10.20.103.237 -- 'wget https://ghproxy.com/https://github.com/rustdesk/rustdesk/releases/download/1.1.6/rustdesk-1.1.6.exe -O /dev/stdout' > rustdesk-1.1.6.exe

如果你本机不能连互联网,而某个服务器能够的话。

反过来也是能够的:

wget https://ghproxy.com/https://github.com/rustdesk/rustdesk/releases/download/1.1.6/rustdesk-1.1.6.exe -O /dev/stdout | sshpass -p $xx -- ssh haha@10.20.103.237 -- 'cat > rustdesk-1.1.6.exe'

备注

其实晓得命令该怎么切会更好了解。答案是,先依照空格(引号外的没本义的)切,再依照管道符 | 切。

双横线 -- 只是对命令传入参数的一个,能够省略,反对不省略的时候倡议写上,帮你对一个命令进一步划分档次。

更多 SHell 常识能够看这个。


分享注明起源: https://segmentfault.com/a/1190000040324158

退出移动版