#前言

懒真的是人类进步的究极动力= =
因为代码要在无数台机器上来回切换,我最开始用的是github,但是频繁改的时候github也太难用了。
后来用微云同步助手,不过这个只能我的windowsmac之间同步,linux没有客户端。
再后来知道了rsync这么一个工具,windows下也有,就三端同步特别方便,写一个命令行工具这边点一下同步到云,那边点一下从云上拉下来,完美。
再后来,也就是昨天,我实在懒得点那一下了,Linux内核支持文件的细粒度监控,用inotify实现,所以一下文件修改增加什么的都可以被监控到,然后自动监控,然后传上云,配合上vscode之类的编辑器的自动保存,感觉解放了自己!

本来想昨晚整理的,结果偷了个懒,就今天了= =!

#inotify 是个啥

一句话概括就是:Inotify 是一个 Linux 特性,它监控文件系统操作,比如读取、写入和创建。

它相比于cron来讲的好处就是事件触发,不会占用大量的计算机资源和时间来扫描,一旦有修改之类的操作,会通知给用户,然后以此来响应操作。

而且inotify是内核支持的。

#安装 inotify-tools

我是在Windows的子系统里装的Ubuntu,听说是个具有完备功能的Linux版本,所以像这种功能应该都有的:

1
2
3
$ inotifywait
Command 'inotifywait' not found, but can be installed with:
sudo apt install inotify-tools

所以其实安装很简单:

1
sudo apt install inotify-tools -y

#使用 inotify-tools

inotify-tools里附带两个工具:inotifywaitinotifywatch

前者用来监控文件或目录的变化,后者用来统计文件系统访问的次数
后者今天暂时用不上,贴个参数,留待有缘人补坑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
$ inotifywatch --help
inotifywatch 3.14
Gather filesystem usage statistics using inotify.
Usage: inotifywatch [ options ] file1 [ file2 ] [ ... ]
Options:
-h|--help Show this help text.
-v|--verbose Be verbose.
@<file> Exclude the specified file from being watched.
--fromfile <file>
Read files to watch from <file> or `-' for stdin.
--exclude <pattern>
Exclude all events on files matching the extended regular
expression <pattern>.
--excludei <pattern>
Like --exclude but case insensitive.
-z|--zero
In the final table of results, output rows and columns even
if they consist only of zeros (the default is to not output
these rows and columns).
-r|--recursive Watch directories recursively.
-t|--timeout <seconds>
Listen only for specified amount of time in seconds; if
omitted or 0, inotifywatch will execute until receiving an
interrupt signal.
-e|--event <event1> [ -e|--event <event2> ... ]
Listen for specific event(s). If omitted, all events are
listened for.
-a|--ascending <event>
Sort ascending by a particular event, or `total'.
-d|--descending <event>
Sort descending by a particular event, or `total'.

Exit status:
0 - Exited normally.
1 - Some error occurred.

Events:
access file or directory contents were read
modify file or directory contents were written
attrib file or directory attributes changed
close_write file or directory closed, after being opened in
writable mode
close_nowrite file or directory closed, after being opened in
read-only mode
close file or directory closed, regardless of read/write mode
open file or directory opened
moved_to file or directory moved to watched directory
moved_from file or directory moved from watched directory
move file or directory moved to or from watched directory
create file or directory created within watched directory
delete file or directory deleted within watched directory
delete_self file or directory was deleted
unmount file system containing file or directory unmounted

inotifywait也先贴一个help

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
$ inotifywait --help
inotifywait 3.14
Wait for a particular event on a file or set of files.
Usage: inotifywait [ options ] file1 [ file2 ] [ file3 ] [ ... ]
Options:
-h|--help Show this help text.
@<file> Exclude the specified file from being watched.
--exclude <pattern>
Exclude all events on files matching the
extended regular expression <pattern>.
--excludei <pattern>
Like --exclude but case insensitive.
-m|--monitor Keep listening for events forever. Without
this option, inotifywait will exit after one
event is received.
-d|--daemon Same as --monitor, except run in the background
logging events to a file specified by --outfile.
Implies --syslog.
-r|--recursive Watch directories recursively.
--fromfile <file>
Read files to watch from <file> or `-' for stdin.
-o|--outfile <file>
Print events to <file> rather than stdout.
-s|--syslog Send errors to syslog rather than stderr.
-q|--quiet Print less (only print events).
-qq Print nothing (not even events).
--format <fmt> Print using a specified printf-like format
string; read the man page for more details.
--timefmt <fmt> strftime-compatible format string for use with
%T in --format string.
-c|--csv Print events in CSV format.
-t|--timeout <seconds>
When listening for a single event, time out after
waiting for an event for <seconds> seconds.
If <seconds> is 0, inotifywait will never time out.
-e|--event <event1> [ -e|--event <event2> ... ]
Listen for specific event(s). If omitted, all events are
listened for.

Exit status:
0 - An event you asked to watch for was received.
1 - An event you did not ask to watch for was received
(usually delete_self or unmount), or some error occurred.
2 - The --timeout option was given and no events occurred
in the specified interval of time.

Events:
access file or directory contents were read
modify file or directory contents were written
attrib file or directory attributes changed
close_write file or directory closed, after being opened in
writable mode
close_nowrite file or directory closed, after being opened in
read-only mode
close file or directory closed, regardless of read/write mode
open file or directory opened
moved_to file or directory moved to watched directory
moved_from file or directory moved from watched directory
move file or directory moved to or from watched directory
create file or directory created within watched directory
delete file or directory deleted within watched directory
delete_self file or directory was deleted
unmount file system containing file or directory unmounted

主要用到的参数是:

  • r:即recursive,递归查询目录。
  • m:即monitor,始终保持监听,如果没有这个参数,inotifywait在接收一次事件之后就会退出。
  • q:即quiet,就是只打印事件,最小化输出。
  • e:即event,我们要监听的事件类型,多个事件用,分隔。

--format参数也会用到,是控制输出格式的,自己看man手册吧如果感兴趣。

首先测试一下监控事件:

1
inotifywait -mrq --format '%Xe %w%f' -e modify,create,delete,attrib Desktop/

然后再开一个shell

1
touch Desktop/{1..5}

然后就会观察到那边的输出:

1
2
3
4
5
6
7
8
9
10
CREATE Desktop/1
ATTRIB Desktop/1
CREATE Desktop/2
ATTRIB Desktop/2
CREATE Desktop/3
ATTRIB Desktop/3
CREATE Desktop/4
ATTRIB Desktop/4
CREATE Desktop/5
ATTRIB Desktop/5

创建文件并修改了属性,没毛病,再改一下文件试试:

1
echo $PATH >> Desktop/1

再次观察到输出:

1
MODIFY Desktop/1

完美!

然后就可以制作一个脚本了,发现检测到了更新,就同步到云端:

1
2
3
4
inotifywait -mrq --format  '%Xe %w%f' -e modify,create,delete,attrib,close_write,move ~/Documents/common/PAN-PyTorch/ | while read file
do
mi
done

这个mi是我自己写的shell,封装了同步的一系列命令,诸位感兴趣可以自己通过rsync来写:rsync 实现文件同步

然后让这个脚本后台运行就行了:

1
nohup osync &

当然也可以做成service把 ngrok 服务配置成 service

收工!

#TODO

刚刚其实测试是在我树莓派的Ubuntu系统下做的,在Windows的子系统里,我发现一个修改事件会触发四次inotify的监控事件,所以其实如果运行下来,修改一次就会进行四次的同步操作,感觉很消耗资源,不过所幸自己用,到时候再来填坑吧!

第二个也是下面参考链接一里提到的问题,其实我每次同步都是全量同步,因为我同步内容少,所以就不麻烦的去弄这些了,如果要真实的应用场景,还是要像他那样按需同步,有空来看看他怎么写的,shell好久没学了,学业压力好大,没时间再做别的了,哭了。

10:19,收工。

#参考链接