如何在脚本内的 rsync 调用中添加参数数组?

如何在脚本内的 rsync 调用中添加参数数组?

我想将文件夹复制到另一个位置,同时排除某些特定文件

这是我当前的脚本:

#!/bin/bash

if [ -n "$2" ]
then
    source=$(readlink -f $1)
    destination=$(readlink -f $2)
else
    printf "\nProper syntax: my_copy source_folder destination_folder\n"
        exit
fi


params=(
    --exclude='.git'
    --exclude='deploy'
    --exclude='app/config/database.php'
    --exclude='app/config/config.php'
)


cd $source
rsync " -a ${params[@]} $source/* $destination"

当我运行脚本时,出现以下错误:

rsync: link_stat "-a --exclude=.git" failed: No such file or directory (2)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1070) [sender=3.0.9]

我究竟做错了什么?

答案1

要查看发生了什么,请先将rsync命令更改为echo命令。

$ echo "rsync \" -a ${params[@]} $source/* $destination\""

潜在的修复

我会将该行更改为:

$ rsync -a "${params[@]}" "$source/"* "$destination"

答案2

如果你写的是这样的:

rsync " -a $params $source/* $destination"

那么该rsync命令将获取单个字符串作为其参数,因为所有变量都在双引号内展开。例如,如果$paramsis --exclude=.git$sourceis/somewhere$destinationis/elsewhere那么参数将是

 -a --exclude=.git /somewhere/* /elsewhere

还有一个额外的问题:"${params[@]}"将数组拆分为单独的参数。前面的文本${params[@]}附加到第一个数组元素,后面的文本${params[@]}附加到最后一个数组元素。所以rsync用四个参数调用:

 -a --exclude=.git
--exclude=deploy
--exclude=app/config/database.php
--exclude=app/config/config.php /somewhere/* /elsewhere

每个参数必须是单独的双引号字符串。您需要双引号来保护变量的扩展,以防它们包含空格或通配符。对于用 展开的数组${NAME[@]}"${NAME[@]}"将每个元素放在单独的参数中。分隔元素的空格以及用作通配符的字符必须保持不带引号。

rsync -a "${params[@]}" -- "$source"/* "$destination"

这不包括直接位于下面的点文件$source,因为/.要将文件复制到 下$source的同名文件中$destination,只需在源目录的路径后添加斜杠即可。

rsync -a "${params[@]}" -- "$source/" "$destination"

相关内容