我想将文件夹复制到另一个位置,同时排除某些特定文件
这是我当前的脚本:
#!/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
命令将获取单个字符串作为其参数,因为所有变量都在双引号内展开。例如,如果$params
is --exclude=.git
、$source
is/somewhere
和$destination
is/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"