在USB钥匙上同步时,如何替换冒号?


12

我想将邮件目录备份到USB闪存盘上。但是,我的IMAP有一个奇怪的命名约定,即某些东西包含冒号(:)字符。由于USB为窗口格式,因此rsync无法创建这些文件。运行rsync时,是否可以用下划线替换冒号?(或与其他工具进行相同的同步?)

我在评论中澄清了几点:

  • 这是最坏情况的备份,我希望能够在Windows计算机上读取它而无需安装任何内容。
  • 我有很多数据保持不变。因此,如果我拥有只复制较新文件的工具,则可以节省大量时间。
  • 我不希望重写rsync。我正在寻找可以直接使用的现有工具。

谢谢

Answers:


8

使用rdiff-backup而不是普通的rsync。它会自动检测并替换目标磁盘上不支持的字符,并且还可以将它们恢复到unix文件系统时的状态。它产生一个看起来像原始文件的解压缩目录,外加一个额外的元数据目录。


6

最直接的方法是利用文件系统层来转换文件名。从Ubuntu 12.04开始,有一个FUSE文件系统可以将文件名转换为Windows的VFAT支持的名称:fuse-posixovl 安装保险丝-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 globstarsetopt 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说传递-pucp实用程序,以便保留权限并仅复制更新的文件。(我们可以告诉zsh执行更新检查;这会更快一点,但会变得更加神秘。)
  • (.)仅选择常规文件。-Q表示将其解析为glob限定符,而不是解析为.带有圆括号的子表达式。
  • $1$2在替换文本中匹配括号表达式(**/)*。(**除非位于括号中,否则将失去零或多个子目录级别的特殊含义,除非括号中包含**/。)

最初,我考虑使用pax,它是一种具有文件重命名功能(其-s选项)的存档工具(此处旨在以传递模式使用)。但是,-s-u选项不能一起使用(paxPOSIX定义从字面上说-u必须检查目标树中具有相同名称的文件,而不是由转换后的文件名-s; Ubuntu中的pax实现从字面上遵循规范,而不是遵循规范。有用)。仍然可以使用它来创建重命名的硬链接,然后将硬链接(使用rsync -aupax -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/

我将尝试使用pax。也许您可以通过在ubuntu上指定所需的软件包来改善答案。它似乎不是正常安装的一部分。
GuillaumeCoté10年

只需添加一个名为pax的软件包即可使其工作。
GuillaumeCoté10年

它不输出任何内容,我尝试添加-v选项以查看发生了什么。似乎每次都在复制所有内容。rsync的重点是增量式的,这使我在很多文件中间只有几个修改后的文件时节省了很多时间。
纪尧姆·科特

它似乎正在我指定的路径下创建一个“主”目录。建议避免在脚本中更改目录,还有另一种可能性避免创建所有这些目录?
GuillaumeCoté2010年

第二遍花了五分钟,一切都一样。rsync只需要几秒钟。是否需要指定一个选项以使其递增?
GuillaumeCoté10年

-1

我对USB记忆棒和移动USB磁盘所做的工作是将它们分为2个分区:FAT32分区和ext4分区。我可以使用第一个与非Linux用户交换数据,第二个用于我与Ubuntu系统的个人使用(并且可能与其他Linux用户交换)。在ext4分区上,不会出现“:”问题。


我希望备份在任何地方都可读,以防我需要在Windows计算机上获取信息。如果没有,我将把usb密钥重新格式化为unix文件系统。这就是为什么我要问替代问题。
GuillaumeCoté10年

嗯,这可以在Windows上至少读的ext2 / ext3的,如果你安装一些工具或文件系统驱动程序。您是否希望能够在每个Windows系统上阅读或仅在您自己的系统上阅读(如果需要,可以在其中安装必要的工具)?
2010年

顺便说一句:从理论上讲,也应该可以将其存储在NTFS系统上,但是大多数Windows应用程序(包括大多数Microsoft应用程序)都不正确支持NTFS ...:P
2010年

这是最坏的情况下的恢复备份,因此当我需要快速处理某些事情时,我想做好准备,但我无权在计算机上安装任何内容。
GuillaumeCoté10年

-2

您可以tar用来创建档案。这样,您无需更改名称即可将其保存到所需的任何文件系统中。


我可以对zip文件或tgz进行相同的操作,但是它将重写每次都没有更改的文件。由于介质的写入次数有限,并且我获得了数个Gib数据,因此我想避免仅重写整个事情,而只是添加了一个新的1kb文件。
GuillaumeCoté10年

通常,将最近闪存上的重写“限制”为数百万或至少数十万。我怀疑您打算进行那么多备份。;)
JanC

2
-1 -azv不会创建一个档案,它确实意味着它保持文件归档模式复制属性
若奥·平托

对不起,我真的以为rsync可以做到这一点,改成了tar,但是我不知道tar是否可以进行增量备份。但是JanC是正确的,重写应该不是问题。
大卫2010年

关于JanC关于重写的评论,不仅是存在限制的事实(我上次检查时接近一千,一百万接近),还有一个事实是我不想等待几个小时才能完成应该少于一分钟。
GuillaumeCoté10年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.