Linux目录双向同步完全指南:Unison从入门到实战
在日常工作和运维中,我们经常遇到这样的需求:两个目录 A 和 B
都可能随时新增或修改文件,希望它们最终保持完全一致,同时绝不能删除任何文件。这种场景下,传统的
rsync 单向同步方案显得力不从心,而 Unison
正是解决这一问题的利器。
本文将深入讲解 Unison 的安装、使用、冲突处理机制,以及如何安全地实现双向同步。
一、为什么 rsync 不够用?
很多人首先想到的是 rsync,但它的局限很明显:
1 | # 这条命令无法实现真正的双向同步 |
问题所在
rsync本质是单向 工具,只能从源到目标。--update只保护目标端的新文件,不会反向同步。- 即使执行两次
rsync, 也无法安全处理两边同时新增或修改的场景。
结论
纯新增文件(从不修改)的场景可以用两次rsync拼凑,但是只要涉及修改,就需要真正的双向同步工具。
二、Unison 简介
Unison 是一款跨平台的双向文件同步工具,核心特性:
- 真正的双向同步: 自动检测并传播两边的变更
- 安全第一: 冲突时不会自动覆盖,需要明确处理
- 增量传输:只同步差异部分,节省带宽和时间
- 跨平台:
Linux、macOS和Windows均可使用 - 支持SSH: 可同步远程服务器目录
安装 Uniso
1 | sudo pacman -S uniso |
基础用法
最简单的双向同步
1 | unison /path/to/A/ /path/to/B |
执行后,Unison会扫描两个目录,并逐一询问如何处理每个差异。
自动模式(跳过非冲突确认)
1 | unison -auto /path/to/A/ /path/to/B/ |
- 作用:自动接受所有非冲突的变更(新增、更新、删除)
- 冲突:仍然会停下等待用户选择
完全静默模式(适合脚本/写明任务)
1 | unison -batch /path/to/A/ /path/to/B/ |
- 作用:不问任何问题
- 冲突时:直接跳过,不做任何处理
- 注意:冲突会导致目录不一致,需配合
-prefer newer使用
冲突处理机制
| 模式 | 冲突处理方式 | 适用场景 |
|---|---|---|
| 默认(交互) | 停下来询问用户选择 | 重要数据,需要人工判断 |
-auto |
停下来询问 | 同上 |
-batch |
直接跳过,不处理 | 不适合,除非配合-prefer |
-batch -prefer newer |
自动选择修改时间更新的版本 | 日志、缓存等可自动决策的数据 |
-batch -prefer A |
始终以A为准覆盖B |
有明确主次的同步 |
Firefox禁用翻译功能
Firefox 的网页翻译功能我不需要,所以需要彻底关闭它。操作路径为:
在地址栏输入
about:config并回车,点击“接受风险并继续”。在搜索框内,将以下两个配置项的值分别双击,修改为
falsebrowser.translations.enable:将此值设为false,会完全禁用整个翻译功能,包括地址栏的翻译按钮.browser.translations.automaticallyPopup:将此值设为false,仅禁止翻译面板自动弹出,但翻译功能仍可用(不会经常跳出来打扰你).
注意:
about:config是Firefox的高级设置,修改前请确认你了解其作用。不过,这两个翻译相关的选项非常安全,可以随时改回true恢复功能。
ArchLinux网络图标问题的解决
我的主力办公系统是 ArchLinux
,最近由于无法访问外网,Gnome
任务栏上的网络小图标显示为一个小问号,虽然可以访问内网,但这个问号总是让人看着不爽。这通常是
NetworkManager 的连接性检查(
Connectivity Check )功能无法成功访问其验证服务器导致的,
所以将检查服务器更换为一个在自己网络下总是能访问的地址将是最优雅的解决办法。解决方法为:
方案一:修改连通性检查的服务器地址(推荐)
- 创建或编辑配置文件
1 | sudo nvim /etc/NetworkManager/conf.d/20-connectivity.conf |
- 添加或修改为以下内容
1 | [connectivity] |
uri指向连通性检查的地址response留空,NetworkManager将只检查HTTP状态码(204表示成功), 这很适合此处使用interval是检查间隔(秒)重启
NetworkManager服务使配置生效
1 | sudo systemctl restart NetworkManager |
方案二:完全禁用连通性检查
- 创建或编辑配置文件
1 | sudo nvim /etc/NetworkManager/conf.d/20-connectivity.conf |
- 添加或修改为以下内容
1 | [connectivity] |
- 重启
NetworkManager服务使配置生效
1 | sudo systemctl restart NetworkManager |
使用Caddy反向代理本地域名
由于网络限制,升级了脚本diary.sh,
从而实现了无法上github的电脑上本地托管博客的功能,这样在办公环境中可以使用高度自定义的博客,进而提高办公规范和效率。然而,借助python3实现的博客工作于本地域名127.0.0:4000或http://localhost:4000,
虽然实现了功能,但是还需要修改firefox的主而为http://localhost:400,
在地址栏中看起来不爽,所以本节是锦上添的技术:使用Caddy反向代理,生成自签名证书,从而实现访问https://fungzhenhua.github.io时实际上是访问http://localhost:4000效果。
配置Caddy
安装Caddy
1 | sudo pacman -S caddy |
配置Caddy, 使用自签名证书
1 | fungzhenhua.github.io { |
测试配置是否正确
1 | sudo caddy validate --config /etc/caddy/Caddyfile |
如果看到Valid configuration字样,说明配置正确,字样通常在最后一行。
启动Caddy
1 | sudo systemctl enable caddy |
重启Caddy
1 | sudo systemctl restart caddy |
Firefox导入证书
在完成上述Caddy设置后,发现每次打开Firefox后总是有风险提示,为了应对这个麻烦需要使用Firefox导入由Caddy生成的证书。由于使用tls internal方式,则Caddy默认生成的证书存放于/var/lib/caddy/pki/authorities/local/root.crt,
访问它需要root权限,于是解决方案是将其复制到家目录,然后赋于读写权限,再导入到Firefox的证书分布机构则问题可解决。
具体操作
1 | # 复制到当前目录 |
如果是其他的Linux发行版,则需确认具体root.crt的路径。
在Firefox中导入
- 打开
about:preferences#privacy - 点击
查看证书... - 切换到
证书颁发机构标签页(注意:不是您的证书标签页) - 点击
导入 - 选择
~/caddy-root.crt - 勾选三个信任 → 确定
本地博客搭建教程
需求分析及工作原理
近期由于网络的原因需要在本地搭建博客,最初的方案是借用Github Pages
实现了自定义博客,但是并非所有的地方都能访问Github,
因此在这些地方可以采用本地博客的方式,实现原理为:
- 将
Github博客源码库同步到Gitee, 因为Gitee属于国内的开发平台,所认其速度非常快。 - 将
Gitee上的源码hexosurce克隆到本地。 - 如果本机可以访问
Github, 则同步克隆其上源码到本地。 - 编辑
Gitee上克隆下来的源码,如果本机不可访问外网,则启动本机http服务,直接访问 http://localhost:4000 - 编辑
Gitee上克隆下来的源码,如果本机可访问外网,将编辑好的源码复制到Github库一份,并Push到Github上,实现同步备份之目的。
使用 Python 内置服务器本地托管博客
安装 Python3
1 | sudo pacman -S python3 |
创建服务文件
1 | [Unit] |
重要
WorkingDirectory必须是博客根目录(即包含public文件夹的目录),而不是public本身。User建议填写你的普通用户名,不要用root。
重新加载并启动
1 | sudo systemctl daemon-reload |
如果状态为 active (running),即可通过
http://localhost:4000 访问。
Wacom的配置和使用
今天网购的数位板Wacom PTK670 收到了,做工相当精制,铝合金机身,超薄设计,厚度仅有4mm, 使用体验了一下,相当好用。我的电脑装配的是 ArchLinux 系统,而 Linux 内核默认是包含 Wacom 驱动的,这也构成了我选择 Wacom 的理由,同时在使用 Gnome+wayland 的组合中不需要任何设置就能完美运行。
ArchLinux 的设置
安装支持手写的软件
xournall++和Openboard1
sudo pacman -S xournalpp openboard
配置快捷键,支持更高效的工作。Wacom PTK670 左右各有一个滚轮和四个方向键,根据操作的频繁程度,我规划了自定义键:
- 打开设置:设置→ 数位板→自定义功能
- 左侧:转轮逆时针向上,顺时针向下, 上键对应
PgUp, 下键PgDn, 左键Ctrl Z撤销,右键Ctrl y, - 右侧:转轮逆时针缩小,顺时针放大,
上键对应
Ctrl+Shift+Delte删除当前页, 下键Ctrl+D新增一页, 左键保留,右键保留.
设置触控笔
- 压力感应设置,启动
xournalpp, 然后依次点击:编辑→触控笔→最小压力0.01→压力增强4.00. - 触控笔按钮:按钮1
手形工具, 按钮2高亮, 按钮3橡皮.
目前暂做上述设定,在使用中再逐步改善。
书定文件转打印体
将书写的内容复制图片,粘贴到通义千问或DeepSeek中,让Ai帮助识别成打印体,实验的结果是只要字不是非常草,文字和公式都能正确识别,然后让Ai以LaTeX源格式输出,只需复制粘贴到LaTeX文件中即可实现编译成PDF文档。这个方法对于大规模的写解答题的答案等是相当可高效的。
ArchLinux使用PcamanHooks解决GDM恢复默认的问题
ArchLinux 是我的主力办公系统,我配置了完整的 WhiteSur
主题,当然也细致到了使用 WhiteSur 的 GDM 主题。但是我发现有时候系统使用
Pacman 升级后 GDM 主题会恢复到默认状态,其根源在于 GDM (GNOME
显示管理器)的主题是通过直接替换系统文件/usr/share/gnome-shell/gnome-shell-theme.gresource
来实现的。当gnome-shell
软件包升级时,这个文件会被包管理器自动恢复为默认版本,所以美化的登录界面就消失了。
永久解决这个问题的核心思路是让系统在每次gnome-shell更新后,自动重新应用一次WhiteSur主题。在ArchLinux上,最优雅的方式就是使用Pacman钩子(hook),
具体步骤为:
创建钩子文件:使用
root权限在/usr/share/libalpm/hooks/目录下创建一个新的钩子文件,例如命名为reapply-whitesur-gdm.hook, 如果你按装了nvim则执行1
sudo nvim /usr/share/libalpm/hooks/reapply-whitesur-gdm.hook
编写钩子内容:
1
2
3
4
5
6
7
8
9[Trigger]
Operation = Upgrade
Type = Package
Target = gnome-shell
[Action]
Description = Reapplying WhiteSur GDM theme after gnome-shell upgrade...
When = PostTransaction
Exec = /bin/sh -c 'cd /路径/你的/WhiteSur-gtk-theme && sudo ./tweaks.sh -g'[Trigger]部分:定义了钩子的触发条件, 即gnome-shell或gdm包升级(Upgrade)后触发。[Action]部分:定义了要执行的动作。Exec: 最关键的一行。它需要指定一个完整的shell命令来重新应用主题。
原理验证:保存文件后,这个钩子就生效了。下一次当你运行
sudo pacman -Syu并且更新列表里包含gnome-shell或gdm时,你会在升级输出中看到你设置的Description文字,随后主题会被自动重新应用。升级完成后,你的GDM登录界面将保持为WhiteSur 主题,再也不会被重置了。
ArchLinux安装兄弟DCP7180DN打印机
近期更换了办公室,所以需要安装该办公室的打印机兄弟DCP7180DN打印机,但是我的ArchLinux 上没有相应的驱动,所以需要安装。
安装打印机配置程序
安装system-config-printer, 打开终端运行命令
1 | sudo pacman -S system-config-printer |
安装brother-dcp7180dn驱动
- 使用
paru检索驱动1
paru -Ss brother |grep 7180
- 确定驱动的全称
brother-dcp7180dn, 执行安装1
paru -S brother-dcp7180dn
配置打印机
在菜单中找到
打印机设置→解锁→添加→网络打印机.选择局域网内的打印机,此时输入打印机的
IP和使用默认端口9100, 同时下方显示连接AppSocket/HP JetDirect, 点击转发, 然后等待搜索驱动.由于已经安装了
brother-dcp7180dn驱动,所以点击确定后就可以使用了。
参考文章
Linux中的排序命令sort
在给学生上完课后,我需要将希沃白板的板书保存下来,合成为一个 PDF
文件,发送给学生,以便学生能够及时复习。但是,在板书超过10页后,发现直接使用
magick 命令合成,那第
10页会跑到第1页前面,于是我修改文件名后完成了操作。但是这也太麻烦了,于是决定编写一个脚本自动处理合成任务,其中的关键是根据
seewo
白板按时间加页码命名的默认方式进行排序。为了完成正确的排序,需要借助sort
命令。
sort 命令简介
| 排序需求 | 命令示例 | 说明 |
|---|---|---|
| 默认字典序(ASCII顺序) | ls \| sort |
最基本排序,大写字母(A-Z)排在小写字母(a-z)之前。 |
| 智能版本序(含数字时推荐) | ls \| sort -V |
能识别数字并按数值大小排,将 1, 2, 10 排成 1, 2, 10(而不是 1, 10, 2)。 |
| 忽略大小写 | ls \| sort -f |
将 a.png 和 B.png 视为相同字母排序。 |
| 按修改时间(时间倒序) | ls -t |
注意:这是 ls 命令的参数 (-t),不是 sort 的功能。 |
| 反转排序结果 | ls \| sort -r |
-r 参数可与其他参数组合,如 sort -Vr 为版本序反转。 |
核心用法
sort 通常不直接操作文件,而是对它接收到的文本输入流进行排序。因此,你需要先用 ls、find 或 echo 生成文件列表,再通过管道 | 传给 sort。
图片合成 pdf 命令
1 | magick $(ls *.png | sort -V) output.pdf |
进阶技巧
如果你想获得类似文件管理器那种“按名称排序,但文件夹在前”的列表,可以结合 ls 和 sort:
1 | ls -la | sort -k 9 # 按第9列(默认文件名列)排序 |
注:这种方法比较脆弱,因为 ls -l 的输出格式固定,列位置可能因系统而异。