我的问题与How to copy multiple files from a different directory using cp?
非常相似我不想使用显式循环。这是我的工作:
$ FILES_TOOLS="fastboot,fastboot-HW.sh"
$ cp $HOME/tools/{$FILES_TOOLS} $TOP_DIR/removeme
cp: cannot stat `/home/johndoe/tools/{fastboot,fastboot-HW.sh}': No such file or directory
文件存在且目的地有效,因为:
$ cp $HOME/tools/{fastboot,fastboot-HW.sh} $TOP_DIR/removeme
$ echo $?
0
答案 0 :(得分:2)
此答案仅限于bash。
预先echo
查看cp
命令变成什么:
echo cp $HOME/tools/{$FILES_TOOLS} $TOP_DIR/removeme
您必须在子shell中插入eval
才能使其正常工作:
cp $( eval echo $HOME/tools/{$FILES_TOOLS} ) $TOP_DIR/removeme
答案 1 :(得分:1)
我想这是实际发生shell扩展的问题。
是。不同的shell对于与变量扩展相关的大括号扩展有不同的规则。你的方式适用于ksh,但不适用于zsh或bash。 {1..$n}
适用于ksh和zsh但不适用于bash。在bash中,变量扩展总是在大括号扩展后发生。
你在bash中最接近这一点的是eval
。
答案 2 :(得分:1)
只要大括号的内容是文字,您就可以使用大括号扩展来填充要复制的文件的完整路径名的数组,然后在cp
命令中展开数组的内容。
$ FILES_TOOLS=( $HOME/tools/{fastboot,fastboot-HW.sh} )
$ cp "${FILES_TOOLS[@]}" $TOP_DIR/removeme
更新:我意识到你可能有理由在变量中单独使用基本名称。这是另一个基于数组的解决方案,它允许您使用路径为数组的每个元素添加前缀,同样没有显式循环:
$ FILES_TOOLS=( fastboot fastboot-HW.sh )
$ cp "${FILES_TOOLS[@]/#/$HOME/tools/}" $TOP_DIR/removeme
在这种情况下,您使用模式替换运算符将每个数组元素开头的空字符串替换为目录名。