我想将邮件目录备份到USB闪存盘上。但是,我的IMAP有一个奇怪的命名约定,即某些东西包含冒号(:)字符。由于USB为窗口格式,因此rsync无法创建这些文件。运行rsync时,是否可以用下划线替换冒号?(或与其他工具进行相同的同步?)
我在评论中澄清了几点:
- 这是最坏情况的备份,我希望能够在Windows计算机上读取它而无需安装任何内容。
- 我有很多数据保持不变。因此,如果我拥有只复制较新文件的工具,则可以节省大量时间。
- 我不希望重写rsync。我正在寻找可以直接使用的现有工具。
谢谢
我想将邮件目录备份到USB闪存盘上。但是,我的IMAP有一个奇怪的命名约定,即某些东西包含冒号(:)字符。由于USB为窗口格式,因此rsync无法创建这些文件。运行rsync时,是否可以用下划线替换冒号?(或与其他工具进行相同的同步?)
我在评论中澄清了几点:
谢谢
Answers:
使用rdiff-backup而不是普通的rsync。它会自动检测并替换目标磁盘上不支持的字符,并且还可以将它们恢复到unix文件系统时的状态。它产生一个看起来像原始文件的解压缩目录,外加一个额外的元数据目录。
最直接的方法是利用文件系统层来转换文件名。从Ubuntu 12.04开始,有一个FUSE文件系统可以将文件名转换为Windows的VFAT支持的名称:fuse-posixovl 。
sudo mount.posixovl /media/sdb1
chown guillaume /media/sdb1
rsync -au ~/mail /media/sbd1/
或为避免要求root访问:
mkdir ~/mnt
/sbin/mount.posixovl -S /media/sdb1 ~/mnt
rsync -au ~/mail ~/mnt/
在文件名是VFAT不接受的字符编码为%(XX)
其中XX
是十六进制数字。从POSIXovl 1.2.20120215开始,请注意,像这样的文件名%(3A)
本身会被编码,并且会被解码为:
,因此,如果文件名包含形式为的子字符串,则存在冲突的风险%(XX)
。
注意POSIXovl不能处理太长的文件名。如果编码的名称不能包含255个字符,则无法存储该文件。
POSIXovl将Unix权限和所有权存储在名为的文件中.pxovl.FILENAME
。
以下bash≥4脚本复制~/mail/foo:bar
到/media/usb99/mail/foo_bar
,并类似地复制到下的所有文件~/mail
。目标树中已经存在且不早于源文件的文件将被跳过。
#!/bin/bash
set -e
shopt -s dotglob globstar
for source in "$HOME"/mail/**/*; do
target=/media/usb99/${source#"$HOME"/}
target=${target//:/_}
if [[ -d $source ]]; then
mkdir -p -- "$target"
elif [[ $target -ot $source ]]; then
cp -p -- "$source" "$target"
fi
done
这个脚本的zsh下工作稍作修改:更换shopt -s dotglob globstar
由setopt dot_glob
和[[ $target -ot $source ]]
通过[[ ! -e $target || $target -ot $source ]]
。
这是zsh的2线(如果算上自动加载,则为3)。它比较短,但是相当先进,而且不太可读。
autoload zargs zmv
zargs -- ~/mail/**/*(/e\''REPLY=/media/usb99/${${REPLY#$HOME/}//:/_}'\') -- mkdir -p --
zmv -C -Q -o -pu '~/mail/(**/)(*)(.)' '/media/usb99/mail/${1//:/_}${2//:/_}'
zargs
行与等效mkdir -p ~/mail/**/*(…)
,除了目录名的累积长度过长时不会炸开。该行将根据需要创建目标目录。~/mail/**/*(/)
扩展到其下的所有目录~/mail
(目录仅归因于(/)
末尾)。(/e\''…'\')
仅选择目录,然后进一步执行“…”内的代码以转换每个文件名,该文件名存储在REPLY
变量中。${${REPLY#$HOME/}//:/_}
删除与源目录相对应的前缀,然后更改:
为_
。zmv -C
将匹配其第一个操作数(zsh模式)的每个文件复制到通过扩展其第二个操作数获得的文件名。-o -pu
说传递-pu
给cp
实用程序,以便保留权限并仅复制更新的文件。(我们可以告诉zsh执行更新检查;这会更快一点,但会变得更加神秘。)(.)
仅选择常规文件。-Q
表示将其解析为glob限定符,而不是解析为.
带有圆括号的子表达式。$1
并$2
在替换文本中匹配括号表达式(**/)
和*
。(**
除非位于括号中,否则将失去零或多个子目录级别的特殊含义,除非括号中包含**/
。)最初,我考虑使用pax,它是一种具有文件重命名功能(其-s
选项)的存档工具(此处旨在以传递模式使用)。但是,-s
和-u
选项不能一起使用(pax的POSIX定义从字面上说-u
必须检查目标树中具有相同名称的文件,而不是由转换后的文件名-s
; Ubuntu中的pax实现从字面上遵循规范,而不是遵循规范。有用)。仍然可以使用它来创建重命名的硬链接,然后将硬链接(使用rsync -au
或pax -rw -pp -u
)复制到其他媒体上,但这带来的麻烦超出了其价值。
cd ~/mail
mkdir -p /media/usb99/mail
pax -rw -l -pp -s '!:!_!g' . ../mail.colonless
rsync -au ../mail.colonless/ /media/usb99/mail/
我对USB记忆棒和移动USB磁盘所做的工作是将它们分为2个分区:FAT32分区和ext4分区。我可以使用第一个与非Linux用户交换数据,第二个用于我与Ubuntu系统的个人使用(并且可能与其他Linux用户交换)。在ext4分区上,不会出现“:”问题。
您可以tar
用来创建档案。这样,您无需更改名称即可将其保存到所需的任何文件系统中。