w开启生长之旅!这是我参加「日新方案 2 月更文应战」的第 4 天,点击查看活动详情

前语

若干年前,我曾对面试者问出过一个类似的问题:有哪些长途传输文件的指令?

他的答复令我十分意外:

  • 答:运用rzsz

  • 我:假如没有xshell之类的软件呢?

  • 答:那就下载一个

  • 我:emmmm…….,还有其他指令么?

  • 答:不会了

  • 我:emmmm…….

尽管标题里的千千万有些夸大,但跨主机传输文件的指令可是真不少的。下面就来介绍些我曾经用过的那些文件传输指令吧!

脚本语言也能够

许多脚本语言都能够临时发动一个http server。于是咱们便能够经过浏览器来下载一些文件

Python

Python能够临时发动一个http server来提供文件拜访

Python 2

$ python -m SimpleHTTPServer 8000

Python 3

$ python3 -m http.server 8000

经过浏览器咱们就能够看到目录能够进行下载

数据同步命令千千万,我却独爱它一个

PHP

发动php内置的服务器之后,尽管咱们没有办法经过浏览器来浏览目录,但能够直接经过浏览器下载文件

$ php -S 0.0.0.0:8000
[Mon Feb 20 15:04:35 2023] PHP 7.4.27 Development Server (http://0.0.0.0:8000) started

鲜为人知的 nc

ncnetcat的简写,有着网络界的瑞士军刀美誉。由于它短小精悍、功用实用,被设计为一个简略、牢靠的网络工具

许多人只知道nc能够用来勘探端口是否打开,功用和telnet类似

$ nc -v 192.168.199.226 1001
nc: connectx to 192.168.199.226 port 1001 (tcp) failed: Connection refused

$ nc -v 192.168.199.226 1000
Connection to 192.168.199.226 port 1000 [tcp/cadlock2] succeeded!

但不知道nc也能够进行端口监听!利用nc端口监听的功用咱们就能够实现文件传输

监听端口

在方针机器上监听端口,并运用管道输出到某文件。注意:下面的-l是小写的L,不是数字1

$ nc -l 1000 > dst/main.go

发送数据

在本地机器上履行

$ nc -v 192.168.199.226 1000 < source/main.go
Connection to 192.168.199.226 port 1000 [tcp/cadlock2] succeeded!

source/main.go就被传输到了192.168.199.226的机器上,并且文件名为dst/main.go

阐明

nc进行文件传输,功用十分简陋,能做的事情不多,但不失为没有其他指令时的应急方案

上面两种方法只能上传或许下载文件,下面来介绍些既能够上传又能够下载的玩法

虚拟终端软件中的rzsz

当咱们运用虚拟终端软件,如Xshell、SecureCRT或PuTTY来衔接长途服务器后,能够运用rzsz来上传下载文件

rz 指令

运用rz指令能够上传本地文件到长途服务器。运转该指令会弹出一个文件选择窗口,从本地选择文件上传到Linux服务器

数据同步命令千千万,我却独爱它一个

sz 指令

将选定的文件发送到本地机器。运转该指令会弹出一个文件选择窗口,从Linux服务器发送到本地(保存的目录是能够配置)

数据同步命令千千万,我却独爱它一个

阐明

rz指令与sz指令常用在虚拟终端软件中,假如是在两台linux直接传输文件,往往是不可行的

传统的sftpftp

sftpftp有着几乎相同的语法和功用,sftp是一个独立的SSH封装协议包,经过安全衔接以类似的方法工作。这意味着只需方针端发动了sshd服务器就能够运用sftp,并且是一种安全传输文件的方法,因此我更推荐你运用sftp

要衔接到长途 sftp 服务器,如下建立一个安全 SSH 衔接并创立 SFTP 会话:

$ sftp wentao@192.168.199.151

登录到长途主机后,你能够如下运转交互式的 sFTP 指令:

sftp> ls -al  # 展示长途主机文件列表
drwxr-xr-x    6 wentao   wheel         192 Feb 19 18:35 .
drwxrwxrwt   13 root     wheel         416 Feb 19 18:26 ..
-rw-r--r--    1 wentao   wheel          73 Feb 19 18:35 main.go
drwxr-xr-x    6 wentao   wheel         192 Feb 19 18:35 sub

sftp> pwd # 长途主机当时途径
Remote working directory: /private/tmp/dst

sftp> lls -al # 展示本地主机文件列表
total 8
drwxr-xr-x  6 wentao  wheel  192 Feb 19 16:54 .
drwxrwxrwt  9 root    wheel  288 Feb 19 18:29 ..
-rw-r--r--  1 wentao  wheel    0 Feb 19 18:30 a
-rw-r--r--  1 wentao  wheel   73 Feb 19 18:30 main.go
drwxr-xr-x  6 wentao  wheel  192 Feb 19 18:25 sub

sftp> lpwd # 本地主机当时途径
Local working directory: /private/tmp/source

上传文件

把本地当时途径下的main.go上传到长途主机当时途径

sftp> put main.go
Uploading main.go to /private/tmp/dst/main.go
main.go

把本地当时途径下的main.go上传到长途主机当时途径,并命名成a.go

sftp> put main.go a.go
Uploading main.go to /private/tmp/dst/a.go
main.go

下载文件

把长途主机当时途径下的main.go下载到本地当时途径

sftp> get main.go
Fetching /private/tmp/dst/main.go to main.go
main.go

仍旧能够自定义名字

sftp> get main.go a.go
Fetching /private/tmp/dst/main.go to a.go
main.go

退出

退出sftp shell能够输入 !

sftp> !

阐明

还有许多图形界面乃至是语言SDK支撑sftp,它的方针不仅仅是传输文件,是历史十分悠久的文件办理协议

功用专注的scp

scp消耗资源少,功用专注,并且加密传输,能够说是最常用的跨主机仿制指令。

cp的指令类似,scp的运用十分简略

scp [参数] [原途径] [方针途径]
  • 第一个途径是原途径,第二个是方针路,两者都能够是长途机器
  • 途径:ssh指令相同,运用@符分割用户名和ip,一同运用:衔接方针目录

把本地文件仿制到长途

$ scp source/main.go wentao@192.168.199.151:/tmp/dst/

把长途机器上的文件仿制到本地

$ scp wentao@192.168.199.151:/tmp/dst/main.go source/

上传目录运用-r

$ scp -r source/* wentao@192.168.199.151:/tmp/dst/

阐明

scp在小文件场景下确实得心应手,但面对大文件或许网络不好需要续传的场景,scp功率就会遭到较大的影响了。此时就是另一个指令的大显神通的时分了。

增量同步的神:rsync

rsync是一种快速且十分通用的文件仿制工具。它运用增量传输算法,该算法仅发送源文件和方针文件之间的差异以削减网络发送的数据量。所以它广泛用于备份和镜像,或作为日常运用的仿制指令

不带任何选项

咱们能够运用rsync进行本地仿制

rsync main.go wentao@192.168.199.151:/tmp/dst

或许把本地文件仿制到长途。和ssh指令相同,运用@符分割用户名和ip,一同运用:衔接方针目录

rsync main.go wentao@192.168.199.151:/tmp/dst

或许把长途机器上的文件仿制到本地

rsync wentao@192.168.199.151:/tmp/source/main.go /tmp/dst

只需意图端的文件内容和源端不相同,并且对源文件的读权限,对方针途径有写权限,就会触发数据同步,rsync就能保证意图端文件同步到和源端共同。(⚠️ 注意是同步文件)

✨【quick check】rsync很聪明,它对两头时间戳和文件巨细共同的文件将不会采纳更新动作。但聪明有时也反被聪明误,假如意图端文件的时间戳、巨细和源端完全共同,可是内容恰巧不共同时,rsync是发现不了的

✨【modify time】rsync不会同步文件的modify time,凡是有数据同步的文件,意图端的文件的modify time总是会被修正为最新时间的时间

✨【rwx权限】rsync不会重视意图端文件的rwx权限,假如意图端没有此文件,那么权限会坚持与源端共同;假如意图端有此文件,则权限不会跟着源端变更

✨【用户和组】rsync只能以登陆意图端的账号来创立文件,它没有才能坚持意图端文件的用户和用户组和源端共同。(除非你运用root权限,才有资格要求用户共同、用户组共同)

✨【删去战略】rsync只保证源目录(运用-r,下文会讲)的一切内容都仿制到方针目录,并且不会删去方针目录的文件

同步文件类型

-r , --recursive:同步文件夹

当咱们不加选项的同步一个文件夹时,rsync会跳过其间的文件夹,仅同步文件

# 跳过了source中的sub文件夹
$ rsync -v source/*  wentao@192.168.199.151:/tmp/dst
skipping directory source/sub
a
main.go

# source都跳过了
$  rsync -v source  wentao@192.168.199.151:/tmp/dst
skipping directory source

加上-r选项,指示需要递归一切文件夹一同同步

$ rsync -vr source  wentao@192.168.199.151:/tmp/dst
building file list ... done
source/a
source/main.go
source/sub/
source/sub/c

-l, --links:同步软链接文件

假如咱们要同步一个软链接文件,你猜rsync会提示什么?

$ ll source/
total 0
lrwxr-xr-x  1 wentao  wheel     9B Feb 18 21:19 d -> outsync/d
-rw-r--r--  1 wentao  wheel     0B Feb 18 20:08 main.go

$ rsync source/d  wentao@192.168.199.151:/tmp/dst
skipping non-regular file "d"

你猜对了,rsync又无情了拒绝了咱们。它一旦发现某个文件是软链接,就会无视它,除非咱们添加-l选项。

$ rsync -l source/d  wentao@192.168.199.151:/tmp/dst

运用了-l选项后,rsync会完全坚持软链接文件类型,原原本本的将软链接文件仿制到意图端,而不会“follow link”到指向的实体文件。

示例中,尽管软链接文件被同步过去了,但由于软衔接指向的文件并没有,所以自然会提示No such file or directory

# wentao@192.168.199.151
➜  dst ll
total 0
-rw-r--r--  1 wentao  wheel     0B Feb 18 20:35 a
-rw-r--r--  1 wentao  wheel     0B Feb 18 20:24 b
lrwxr-xr-x  1 wentao  wheel     9B Feb 18 21:20 d -> outsync/d
➜  dst cat d
cat: d: No such file or directory

假如我偏偏就想让rsync采纳”follow link”的方法,那就用-L选项就能够了

$ rsync -vv -L source/d  wentao@192.168.199.151:/tmp/dst

此时方针端现已不再时软衔接文件了,而是实体文件

➜  dst ll
total 0
-rw-r--r--  1 wentao  wheel     0B Feb 18 20:35 a
-rw-r--r--  1 wentao  wheel     0B Feb 18 20:24 b
-rw-r--r--  1 wentao  wheel     0B Feb 18 21:34 d

--devices:同步块设备文件

块设备也能被同步,但条件是方针端运用super-user用户传输

--specials:同步特别文件

特别文件首要包含着命名socketsfifos

同步文件特点

-p, --perms:同步权限

还记得无选项时说到的rwx权限么?

  • 假如意图端没有此文件,那么在同步后会将意图端文件的权限坚持与源端共同

  • 假如意图端已存在此文件,那么只会同步文件内容,权限坚持原有不变

假如你运用了-p选项,则无论如何,rsync都会让意图端坚持与源端的权限共同的

-t, --times:同步修正时间

还记得无选项时说到的modify time么?rsync不会同步文件的modify time,凡是有数据同步的文件,意图端的文件的modify time总是会被修正为最新时间的时间

假如你运用了-t选项,则无论如何,rsync都会让意图端坚持与源端的修正时间共同的

-g, --group:同步文件用户组

-o, --owner:同步文件用户

还记得无选项时说到的用户和组么?rsync只能以登陆意图端的账号来创立文件,它没有才能坚持意图端文件的用户和用户组和源端共同

这两个选项是一对,用来坚持文件的属组(group)和属主(owner),作用应该很明晰明晰。不过要注意的一点是,改变属主和属组,往往只有办理员权限才能够

复合指令

-a, --archive: -rlptgoD

-a选项,就相当于运用了-rlptgoD这一坨选项,以一敌七。(在看了前文之后,你应该能够很轻松的了解这七个选项的作用了)

  • -r , --recursive:同步文件夹
  • -l, --links:同步软链接文件
  • -p, --perms:同步权限
  • -t, --times:同步修正时间
  • -g, --group:同步文件用户组
  • -o, --owner:同步文件用户
  • -D: 等同于 --devices --specials
    • --devices:同步块设备文件
    • --specials:同步特别文件

用户体验

-v, --verbose:展示日志信息

这个选项简略易懂,就是让rsync输出更多的信息,咱们能够举一个例子:

$ rsync -v main.go wentao@192.168.199.151:/tmp/dst
main.go
sent 84 bytes  received 42 bytes  252.00 bytes/sec
total size is 0  speedup is 0.00

添加越多的v,就能够获得越多的日志信息。

$ rsync -vvvv main.go wentao@192.168.199.151:/tmp/dst
cmd= machine=192.168.199.151 user=wentao path=/tmp/dst
cmd[0]=ssh cmd[1]=-l cmd[2]=wentao cmd[3]=192.168.199.151 cmd[4]=rsync cmd[5]=--server cmd[6]=-vvvv cmd[7]=. cmd[8]=/tmp/dst
opening connection using ssh -l wentao 192.168.199.151 rsync --server -vvvv . /tmp/dst
(Server) Protocol versions: remote=29, negotiated=29
(Client) Protocol versions: remote=29, negotiated=29
[sender] make_file(main.go,*,2)
server_recv(2) starting pid=3420
[sender] i=0 <NULL> main.go mode=0100644 len=0 flags=0
send_file_list done
...

-n, --dry-run:不实际履行

假如担心履行删去等危险操作时误操作,能够运用-n进行测试

加上-n之后并不会真实履行同步,与-v调配则会展示rsync要如何操作每一个文件

$ rsync -n -v --delete -r source/ wentao@192.168.199.151:/tmp/dst
building file list ... done
deleting b
a
main.go

控制同步战略

-I, --ignore-times:不运用quick check

还记得无选项时说到的quick check么?rsync会疏忽两头时间戳和文件巨细共同的文件,以提高传输速度,但有时却会发生问题

$ rsync -I source/main.go  wentao@192.168.199.151:/tmp/dst

-I选项会让rsync变得很乖很老实,它会挨个文件去主张数据同步

-I选项能够保证数据的共同性,价值就是速度上会变慢,由于咱们抛弃了“quick check”战略

--delete:删去方针的文件

还记得无选项时说到的删去战略么?假如在源端删去了某文件,意图端是不会被删去的

当运用了 --delete之后,假如源端没有此文件,那么发送方也别想具有,删去之。(假如你运用这个选项,就必须调配-r选项一同)

-z, --compress:紧缩传输

这是个紧缩选项,只需运用了这个选项,rsync就会把发向对端的数据先进行紧缩再传输,然后减小数据量

关于网络环境较差的情况下主张运用

总结

经过介绍的内容占比大家也能够看出来,我最爱的指令是rsync,但我并不是一切场景都运用它

我最常用的其实是scp。首要它十分简略,消耗资源少,并且大部分linux发行版都自带这个指令

但当要传输十分大或许十分多的文件,或许网络环境不太好的时分,我更喜欢rsync。它运用增量同步的方案,支撑紧缩,因此传输十分快,并且断线之后还能够续传

当主机上没有这两个指令时,我才会测验运用 sfptnc、或许脚本语言等方法

你还知道哪些跨主机文件传输的指令或许方法呢?欢迎谈论区留言评论~

参考文档

  • 《rsync同步的艺术》–linux指令五分钟系列之四十二
  • rsync(1) – Linux man page
  • sftp(1) – Linux man page
  • nc(1) – Linux man page

✨ 微信大众号【凉凉的知识库】同步更新,欢迎重视获取最新最有用的后端知识 ✨