我尝试做scp
多个文件。当我这样做时ls {aaa,bbb}*_list.txt
,我只能看到选择性文件。但是,如果我将其分配给一个变量并尝试在命令中使用它,scp
它将不起作用。
我试过如下
files_to_scp="{aaa,bbb}*_list.txt"
scp $files_to_scp user@host:.
它抛出错误{aaa,bbb}*_list.txt: No such file or directory
。但如果只是复制错误路径 ( {aaa,bbb}*_list.txt
) 并执行ls
,它会显示该文件。这里可能出了什么错误。
答案1
这大括号扩展语法{aaa,bbb}
必须包含大括号和,
不加引号的字符,才能扩展为有效/可能的文件集。在OP中, "{aaa,bbb}*_list.txt"
保持原样作为文字字符串并且根本不扩展。
另外,将大括号扩展存储在变量中并插入该变量来扩展大括号将永远不会起作用,因为大括号扩展发生在任何其他 shell 扩展之前,即当您期望$files_to_scp
扩展大括号时,shell 已经越过展开大括号的点
使用变量是不是持有多个单词的正确方法。如果您的文件名包含空格或其他 shell 特殊字符,它将严重失败。使用数组类型和适当的带引号的扩展
files_to_scp=({aaa,bbb}*_list.txt)
现在将结果用作
scp "${files_to_scp[@]}" user@host:.
答案2
你的变量 ( files_to_scp
) 保存着文字字符串"{aaa,bbb}*_list.txt"
,不是所有匹配文件的扩展。 bash 不会在标量变量赋值上展开大括号。
然而,bash 确实将它们扩展为数组。请改用数组。
例如
files_to_scp=( {aaa,bbb}*_list.txt )
scp "${files_to_scp[@]}" user@host:.
这是一个(简化的、实用的)示例和解释,显示了正在发生的情况:
我创建了一堆与您的模式匹配的文件
$ mkdir spike $ cd spike $ touch {aaa,bbb}{01..10}_list.txt $ ls aaa01_list.txt aaa05_list.txt aaa09_list.txt bbb03_list.txt bbb07_list.txt aaa02_list.txt aaa06_list.txt aaa10_list.txt bbb04_list.txt bbb08_list.txt aaa03_list.txt aaa07_list.txt bbb01_list.txt bbb05_list.txt bbb09_list.txt aaa04_list.txt aaa08_list.txt bbb02_list.txt bbb06_list.txt bbb10_list.txt
您的变量分配存储文字字符串:
$ files_to_scp="{aaa,bbb}*_list.txt" $ declare -p files_to_scp declare -- files_to_scp="{aaa,bbb}*_list.txt"
bash 在不带引号的情况下执行相同的操作:
$ files_to_scp={aaa,bbb}*_list.txt $ declare -p files_to_scp declare -- files_to_scp="{aaa,bbb}*_list.txt"
使用数组,每个匹配的文件名都存储为数组的元素。
$ files_to_scp=( {aaa,bbb}*_list.txt ) $ declare -p files_to_scp declare -a files_to_scp=([0]="aaa01_list.txt" [1]="aaa02_list.txt" [2]="aaa03_list.txt" [3]="aaa04_list.txt" [4]="aaa05_list.txt" [5]="aaa06_list.txt" [6]="aaa07_list.txt" [7]="aaa08_list.txt" [8]="aaa09_list.txt" [9]="aaa10_list.txt" [10]="bbb01_list.txt" [11]="bbb02_list.txt" [12]="bbb03_list.txt" [13]="bbb04_list.txt" [14]="bbb05_list.txt" [15]="bbb06_list.txt" [16]="bbb07_list.txt" [17]="bbb08_list.txt" [18]="bbb09_list.txt" [19]="bbb10_list.txt")