从数组构建的参数在没有eval的情况下无法工作

时间:2014-01-15 21:39:37

标签: bash

我有一个小的rsync脚本:

OPTS="--some --long --opts"
ORIGIN="/folder/xy/"
DESTINATION="/backups/xy/"
EXCLUDES=( "/dir1" "/dir2" "/dir3" )

PREFIXED_EXCLUDES=( ${EXCLUDES[@]/#/"--exclude=\""} ) #prepend <--exclude=">
ESCAPED_EXCLUDES=( ${PREFIXED_EXCLUDES[@]/%/"\""} ) #append <">

(1) echo rsync $OPTS ${ESCAPED_EXCLUDES[@]} $ORIGIN $DESTINATION
(2) rsync $OPTS ${ESCAPED_EXCLUDES[@]} $ORIGIN $DESTINATION
(3) eval rsync $OPTS ${ESCAPED_EXCLUDES[@]} $ORIGIN $DESTINATION

(1)将完全回显我想要的命令

(2)忽略--exclude参数,但仅忽略它们,其他参数起作用

(3)正常运作

为什么没有eval它不起作用?我试图想出一个更简单的例子,但没有想到。

2 个答案:

答案 0 :(得分:2)

我怀疑这会奏效:

EXCLUDE_DIRS=( "/dir1" "/dir2" "/dir3" )
EXCLUDES=()
for dir in "${EXCLUDE_DIRS[@]}"; do
    EXCLUDES+=( "--exclude=$dir" )
done

rsync $OPTS "${EXCLUDES[@]}" "$ORIGIN" "$DESTINATION"

上述所有引用(或缺少引用)都是非常慎重的。

答案 1 :(得分:0)

您需要使用eval,因为在扩展变量后不会处理引号。变量扩展经历了单词拆分和文件名整合,没有处理其他特殊字符;如果变量在双引号内展开,即使这些也不会发生。

你应该写一下:

eval "rsync $OPTS ${ESCAPED_EXCLUDES[@]} $ORIGIN $DESTINATION"

避免额外的单词分裂和全球化。