使用scp时bash数组的扩展
我正在尝试使用 scp 检索多个文件。我已经知道远程文件的路径,所以我决定将它们添加到一个数组中:
declare -a array
array+=("path/to/file1")
array+=("path/to/file2")
array+=("path/to/file3")
scp "$USER@$HOST:${array[@]}" .
输出:
path/to/file1
cp: cannot stat `path/to/file2': No such file or directory
cp: cannot stat `path/to/file3': No such file or directory
只有第一个文件被复制。scp 命令只考虑第一个文件,然后对其余文件调用 cp。
像这样简单的事情使它起作用:
declare -a array
array+=("path/to/file1")
array+=("path/to/file2")
array+=("path/to/file3")
string="${array[@]"
scp "$USER@$HOST:$string" .
输出:
path/to/file1
path/to/file2
path/to/file3
当我使用 bash -x 启动我的脚本时,它显示使用数组时,命令没有正确引用:
+ scp $USER@$HOST:path/to/file1 path/to/file2 path/to/file3 .
与字符串版本相反:
+ scp '$USER@$HOST:path/to/file1 path/to/file2 path/to/file3' .
究竟是什么原因造成的?有没有办法让数组版本工作,或者每次我想使用 scp 时都应该使用字符串?(使用特殊字符可能会很不方便)
回答
使用@多个参数扩展数组:
$ array=(foo bar baz)
$ printf '<%s>n' "${array[@]}"
<foo>
<bar>
<baz>
用*中的第一个字符分隔的单个参数将其展开$IFS:
$ array=(foo bar baz)
$ printf '<%s>n' "${array[*]}"
<foo bar baz>
99% 的命令期望每个参数有一个文件名,但scp由于历史原因,每个参数使用多个文件名。在这种情况下,您可以使用
scp "$USER@$HOST:${array[*]}" .
虽然您可能也想转义文件名,但同样出于历史 scp 原因:
scp "$USER@$HOST:${array[*]@Q}" .