我的意思是rsync
用来删除某些文件(用于高效删除包含数千个文件的大目录),在这种情况下,将其作为命令行中的模式提供给 shell 脚本。
到目前为止,这就是我的 shell 脚本中的内容rsync_del.sh
#!/bin/bash
TARGET_DIR=${1}
shift
PATTERNS="${@}"
for patt in ${PATTERNS} ; do
# Both do the same
#INCLUDE_PATTERNS="${INCLUDE_PATTERNS}"' --include='\'"${patt}"\'
INCLUDE_PATTERNS="${INCLUDE_PATTERNS} --include=\"${pattern}\""
done
EMPTYDIR=$(mktemp -d)
echo "Created empty dir ${EMPTYDIR}"
comm="rsync -a --progress --delete ${INCLUDE_PATTERNS} ${EMPTYDIR}/ ${TARGET_DIR}"
echo ${comm}
eval ${comm}
我想使用的示例模式是*[1-9].txt
,*000??9.txt
。问题是,执行时
rsync_del.sh trg_dir '*[1-9].txt'
生成的命令行是
rsync -a --progress --delete --include='*[1-9].txt' /tmp/tmp.51R9hPgkfG/ trg_dir/
(这对我来说似乎没问题),但它是匹配的,例如,文件之类的input.dat
(我不想要那个)。
实施/使用它的正确方法是什么? 我怀疑这是正确转义模式的问题,但我无法完成这项工作。
注意:我需要在执行echo
之前定义要在变量中执行的命令。
不要太仔细地看这里的实际使用,
rsync
而是专注于rsync
命令行的创建。通过使用数组(
incl
上面的数组),您可以将参数rsync
单独存储,而不是像字符串一样。的扩展"${incl[@]}"
将是数组中单独引用的元素。引用参数变得微不足道,无需调用eval
. 另请注意,所有参数扩展都需要正确地用双引号引起来。您的代码的问题是您使用大多数未加引号的参数扩展。这使得 shell 对变量执行分词和文件名生成(通配)。这反过来意味着您不能使用包含空格的模式或可能扩展到现有文件名称的 shell 通配模式。
因为
/bin/sh
语法变得更加简洁:我忘记了我应该通过排除任何未明确包含的内容来关闭模式列表。我用了