我对borgbackup有这个问题,但是由于反应是相同的,所以我将在我的示例中使用rsync。
我希望通过向每个参数添加一个前缀来构建一个参数数组,然后将该数组交给rsync。但是rsync表现得好像它不存在。
使用此脚本:
#!/usr/bin/env bash
#
declare -a exclude_String
for excludestr in $(cat ./list); do
exclude_String+=(--exclude=$excludestr)
done
rsync "${exclude_String[@]}" . $Destination和./list:
'/home/*'
'*.vim*'进程运行的ps确实正确地显示了参数:
/usr/bin/rsync --exclude='*.vim*' --exclude='/home/*' . DESTINATION但rsync仍然表现得好像他们不存在。我在这个问题上找到了这个问题,所以我试了一下:
#!/usr/bin/env bash
#
declare -a exclude_String
exclude_String+=(--exclude='/home/*')
exclude_String+=(--exclude='*.vim*')
rsync "${exclude_String[@]}" . $Destination而且这个确实奏效了。
我还不太了解壳的扩张和其他东西,我试着引用和双引号到处都是,只是想看看我是否能找到什么,但没有运气。
你知道怎么做到这一点吗?
发布于 2018-07-31 21:48:55
如果文件实际包含'/home/*',带有引号,则引号将在循环中的excludestr值中,然后在给rsync的参数中。在这种情况下,它们不是shell命令的一部分,只是命令替换扩展值的一部分。
另一方面,如果您编写exclude_String+=(--exclude='/home/*'),那么现在引号是shell命令的一部分,并且在处理该命令时被移除。(其效果是使*成为一个普通字符。)
rsync实际上并不期望或处理引号作为排除模式的一部分,它只是将它们视为任何其他字符,并将包含引号的文件排除在外。因此,如果将排除模式作为数据存在于某个文件中,则不应该有引号。
另外,不要使用for x in $(cat file),而是使用while IFS= read -r line; do ...; done < file,或者在本例中使用mapfile -t exclude_String < file。使用cat替换命令会调用单词拆分,因此不能有包含空格的排除模式。它还在for循环的单词列表上立即调用模式的全局化。这不是你想要的。
一般来说,你需要的是:
excludes=()
while IFS= read -r line; do
excludes+=(--exclude="$line")
done < ./list
rsync "$flags" "${excludes[@]}" . "$destination"./list只包含要排除的模式:
/home/*
*.vim*( "$line"在+=(--exclude="$line")中的引号防止shell在当前目录中使名为--exclude=something的文件全局化。)
尽管在rsync的例子中,您最好使用--exclude-from:
rsync "$flags" --exclude-from=./list . "$destination"如果要使用比文件更复杂的内容来填充循环,则可以使用进程替换:
while IFS= read -r line; do
excludes+=(--exclude="$line")
done < <(some command that produces the exclude patterns)发布于 2018-08-01 17:55:02
正如ilkkachu所解释的,您的问题是单引号不应该是模式的一部分,如果在shell上下文中编写模式,shell将删除它们。
但是,看起来您可以不必显式地从文件中读取模式:
rsync --exclude-from=./list source/ target使用--exclude-from=FILENAME,rsync将从命名的FILENAME中读取排除模式。注意,在这样做时,模式中不应该包含那些单引号。
https://unix.stackexchange.com/questions/459705
复制相似问题