如何在bash中正确传递包含*的运行时确定的命令行开关?

时间:2013-12-09 02:07:30

标签: bash rsync

我正在编写一个简单的脚本,rsync是我本地计算机的远程站点,并根据命令行中指定的选项动态生成--exclude=dir标志。

#!/bin/bash -x

source="someone@somewhere.org:~/public_html/live/"
destination="wordpress/"

exclude_flags='--exclude=cache/* '

if [ "$1" == "skeleton" ] ; then
    exclude_flags+='--exclude=image-files/* '
fi

rsync --archive --compress --delete $exclude_flags -e ssh $source $destination

当我尝试在最后一行插入$ exclude_flags变量时,我遇到了麻烦。由于变量中有空格,bash会在插值前后自动插入单引号。这是bash试图执行的命令(/ bin / bash + x的相关输出):

+ /usr/bin/rsync --archive --compress --delete '--exclude=cache/*' '--exclude=image-files/*' -e /usr/bin/ssh someone@somewhere.org:~/public_html/live/ wordpress/

正如你所看到的,bash在$ exclude_flags的各个标记周围插入了一串单引号,这导致rsync被阻塞。

我试过了:

  1. 我上面列出的内容。

  2. 将其放在双引号... "$exclude_flags" ...中。这几乎解决了这个问题,但并不完全。单引号仅出现在$ exclude_flags的完整内容周围,而不是围绕每个标记。

  3. 将$ exclude_flags设为数组,然后使用$ {exclude_flags [@]}进行插值。这给出了与#2相同的输出。

  4. 将整个rsync行包装在后面的勾号中。这给出了与#1相同的输出。

  5. 有什么想法吗?这似乎是bash中一个非常简单和常见的问题,所以我确信我做错了什么,但谷歌根本没有帮助。

    谢谢。

1 个答案:

答案 0 :(得分:0)

bash中的变量中存储多个命令行选项的正确方法是使用数组:

source="someone@somewhere.org:~/public_html/live/"
destination="wordpress/"

options=( '--exclude=cache/*' )
if [[ "$1" == "skeleton" ]] ; then
  options+=( '--exclude=image-files/*' )
fi

rsync --archive --compress --delete "${exclude_flags[@]}" -e ssh "$source" "$destination"
相关问题