Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash rsync带引号路径的多个目录_Bash_Quotes_Rsync_Filepath - Fatal编程技术网

Bash rsync带引号路径的多个目录

Bash rsync带引号路径的多个目录,bash,quotes,rsync,filepath,Bash,Quotes,Rsync,Filepath,我试图在bash脚本内的一次调用中rsync多个目录,但在引用路径的语法方面遇到了麻烦 以下是我正在尝试的: backuppath='/path/to/backup/folders/' declare -a backupitems=('folder1' 'folder2') backupitems=(${backupitems[@]/#/\"$backuppath}) backupitems=(${backupitems[@]/%/\"}) backup=${backupitems[@]} r

我试图在bash脚本内的一次调用中rsync多个目录,但在引用路径的语法方面遇到了麻烦

以下是我正在尝试的:

backuppath='/path/to/backup/folders/'
declare -a backupitems=('folder1' 'folder2')
backupitems=(${backupitems[@]/#/\"$backuppath})
backupitems=(${backupitems[@]/%/\"})
backup=${backupitems[@]}

rsync ${backup} /path/to/destination
我得到一个link_stat错误,说没有这样的文件或目录用于
“/path/to/current/directory”/path/to/backup/folders/folder1”“
,然后folder2出现了同样的错误。因此,它似乎像我所希望的那样生成引用路径,但是rsync将路径解释为相对路径,并将路径添加到前面的当前目录。如果我这样做,rsync工作正常

backuppath='path/to/backup/folders/folder1'
rsync "${backuppath}" /path/to/destination
将引号放在rsync命令中,但我不能在一个变量中使用多个文件夹,因为它将多个目录视为一条长的单一路径。我使用第二种方法使脚本工作,方法是在文件夹上循环并在每个文件夹上调用rsync,但是这种方法稍微有点尴尬,因为脚本的其他部分处理文件夹的方式,所以如果有快速修复方法,我想让第一种方法工作

编辑:

对于上面的顶层版本,任何目录名中都没有空格,我使用
set-vx
看到以下命令: rsync'/path/to/backup/folders/folder1'''/path/to/backup/folders/folder2'/path/to/destination

我得到以下错误消息:

rsync: link_stat "/path/to/current/directory/"/path/to/backup/folders/folder1"" failed: No such file or directory (2)
如果我使用@kdubs建议的版本,那么当路径中没有空格时,一切都可以工作

当路径中有空格时,kdubs version将生成以下命令:

rsync/path/to/backup/folders/folders1/path/to/backup/folders/folders2/path/to/destination

以及错误:

rsync: link_stat "/path/to/back" failed: No such file or directory (2)
rsync: link_stat "/path/to/back up/up/folder1" failed: No such file or directory (2)

我的第一个版本需要对空格进行额外的调整,因为使用[@]扩展数组并使用()封闭扩展创建新数组会导致路径中的空格将路径拆分为多个数组元素(请参见下面Tonin的答案)。

去掉这些引号:

backuppath='/path/to/backup/folders/'
declare -a backupitems=('folder1' 'folder2')
backupitems=(${backupitems[@]/#/$backuppath})
backup=${backupitems[@]}

rsync ${backup} /path/to/destination

去掉那些引语:

backuppath='/path/to/backup/folders/'
declare -a backupitems=('folder1' 'folder2')
backupitems=(${backupitems[@]/#/$backuppath})
backup=${backupitems[@]}

rsync ${backup} /path/to/destination

脚本中的问题在于bash定义数组元素的方式。元素由空格分隔。因此,当您将修改后的数组元素重新分配回数组时,实际上创建的元素比最初创建的元素多。通过在数组声明和每个赋值之后添加
echo${#backupitems[@]}
可以看到这一点

最后,当您在
$backup
变量中展平阵列时,bash甚至让rsync相信它已经给出了相对路径,从而使情况变得更糟

为了解决这个问题,我将使用以下脚本,该脚本使用文件名中的空格(或路径中的任何位置):


脚本重新声明
IFS
变量,该变量在创建数组时会更改有关记录分隔符的bash行为。不过,与您的脚本略有不同的是,
$backup
变量不能再使用了,否则您将在实际使用之前展平数组。希望这不是一个要求。

脚本中的问题在于bash定义数组元素的方式。元素由空格分隔。因此,当您将修改后的数组元素重新分配回数组时,实际上创建的元素比最初创建的元素多。通过在数组声明和每个赋值之后添加
echo${#backupitems[@]}
可以看到这一点

最后,当您在
$backup
变量中展平阵列时,bash甚至让rsync相信它已经给出了相对路径,从而使情况变得更糟

为了解决这个问题,我将使用以下脚本,该脚本使用文件名中的空格(或路径中的任何位置):


脚本重新声明
IFS
变量,该变量在创建数组时会更改有关记录分隔符的bash行为。不过,与您的脚本略有不同的是,
$backup
变量不能再使用了,否则您将在实际使用之前展平数组。我们希望这不是一项要求。

在变量中嵌入引号没有任何用处。最好的方法是在展开变量时在变量周围加上双引号,并将数组展开为“${arrayname[@]}””——这样bash将把数组中的每个元素视为一个单独的单词,即使它们包含空格或其他shell元字符。棘手的事情是在数组的每个元素前面加$backuppath,但是您有正确的方法(除了在其周围加引号,而不是在值中加引号):


在变量中嵌入引号没有任何用处。最好的方法是在展开变量时在变量周围加上双引号,并将数组展开为“${arrayname[@]}””——这样bash将把数组中的每个元素视为一个单独的单词,即使它们包含空格或其他shell元字符。棘手的事情是在数组的每个元素前面加$backuppath,但是您有正确的方法(除了在其周围加引号,而不是在值中加引号):


好问题,欣赏示例代码。但是插入并格式化为代码的实际错误消息将更容易诊断您的问题。还可以尝试使用
set-vx包装对rsync的调用;rsync;设置+vx
。祝你好运。好问题,感谢示例代码。但是插入并格式化为代码的实际错误消息将更容易诊断您的问题。还可以尝试使用
set-vx包装对rsync的调用;rsync;设置+vx
。祝你好运。嗯,对不起,我把示例代码做得太普通了一点。这适用于示例中的路径,但不适用于包含空格的路径,如
/path/to/backup/folders/
——这就是使用引号的动机。啊。那让我想想,别这样
backuppath='/path/with spaces/'
backupitems=('folder 1' 'folder 2')   # declare -a is optional
backupitempaths=("${backupitems[@]/#/$backuppath}")

rsync "${backupitempaths[@]}" /path/to/destination