Windows 现在有一个内置的 openssh 服务器,因此我们也可以使用 rsync 来备份 Windows PC 上的文件夹。问题是,如果我尝试
rsync --relative -aqz --numeric-ids --delete-after -e 'ssh' 's2@black:C:\Users\s2\.gnupg' black
从 Linux 服务器,我最终得到如下所示的本地目录结构:
black/
└── C:\Users\s2\.gnupg
├── crls.d
│ └── DIR.txt
├── gpg-agent.conf
[...]
└── trustdb.gpg
因此根文件夹是名为的单个文件夹C:\Users\s2\.gnupg
,而不是像这样的三个文件夹Users/s2/.gnupg
。有没有办法将 Windows 路径转换为 Linux 路径,以便备份有意义?
答案1
你可以随后将目录合并到
./script black
该脚本使用 GNU find-print0
循环遍历 C: 并创建所有目录、mv
所有文件并删除旧目录。只有问题目录会丢失像 xattrs 这样的元数据(但可以用几行代码轻松克服chown
chcon
等)
脚本
find "$@" -depth -type d -iname 'C:\\*' -print0 | while IFS= read -r -d '' dir || [ "$dir" ]
do
path="${dir%/*}"
dir="${dir##*/}"
mkdir -p "$path/${dir//\\//}"
find "$path/$dir" -maxdepth 1 -not -type d -exec mv {} "$path/${dir//\\//}" +
rmdir "$path/$dir"
done
编辑:
对于混合路径,您需要更多代码进行合并。您可以改用cp -l
通过mv
硬链接移动文件。元数据被保留
脚本
#!/bin/bash
# or sh supporting read -d
# random name
tmp="${0##*/}_$(date '+%s')_tmp~"
# search for windows drive letters 'C:\' in 'black'
find -L "$@" -type d -iname '[A-Z]:\\*' -print0 | sort -z | while IFS= read -r -d '' dir || [ "$dir" ]
do
printf "'%s' -> " "$dir"
# resolve symlinks
dir="$(realpath "$dir")"
path="${dir%/*}"
dir="${dir##*/}"
win="${dir%\\*}"
nix="${dir##*\\}"
printf "'%s'\n" "${dir//\\//}"
# create linux directories
mkdir -p "$path/${dir//\\//}"
# move childs windows -> linux preserving metadata (via hard-links)
find "$path/$dir" -mindepth 1 -maxdepth 1 \( -exec cp -abflPx {} "$path/${dir//\\//}" \; -a -exec rm -r {} \; \)
# rename parent windows -> linux
mkdir -p "$path/$tmp"
mv "$path/$dir" "$path/$tmp/$nix"
# copy parent metadata
rsync -aAX "$path/$tmp/$nix" "$path/${win//\\//}"
# delete windows directories
rmdir "$path/$tmp/$nix" "$path/$tmp"
done
不幸的是,它的速度要慢得多,因为find -exec \;
一些不必要的sort
和echo
答案2
您需要/mnt/c/
先挂载
或使用 cwrsync