我想复制一堆Verilog / systemverilog源代码,所以我使用CP和通配符表达式:
cp <some_dir>/*.{v,sv,svh} .
有效。但是,当我将它放到具有完全相同行的脚本时,CP命令将失败并显示日志:
cp: cannot stat `../../mytest/spiTest/*.{v,sv,svh}': No such file or directory
这是怎么回事?
PS:我使用bash作为shell。
这是我的剧本:
#!/bin/bash
rdir=../../mytest/spiTest
f1="$rdir/bench.lst"
f2="$rdir/cphex" #the script to copy rom data
f3="$rdir/make*" #makefile scripts
f4="$rdir/*.hex" #rom files
f5="$rdir/*.{v,sv,svh}" #testbench files
echo 'Copying files...'
cp $f1 $f2 $f3 $f4 .
cp $f5 .
我确实将第一行改为
#!/bin/bash -vx
再次运行此脚本,我得到:
#!/bin/bash -vx
rdir=../../mytest/spiTest
+ rdir=../../mytest/spiTest
f1="$rdir/bench.lst"
+ f1=../../mytest/spiTest/bench.lst
f2="$rdir/cphex" #the script to copy rom data
+ f2=../../mytest/spiTest/cphex
f3="$rdir/make*" #makefile scripts
+ f3='../../mytest/spiTest/make*'
f4="$rdir/*.hex" #rom files
+ f4='../../mytest/spiTest/*.hex'
f5="$rdir/*.{v,sv,svh}" #testbench files
+ f5='../../mytest/spiTest/*.{v,sv,svh}'
echo 'Copying files...'
+ echo 'Copying files...'
Copying files...
cp $f1 $f2 $f3 $f4 .
+ cp ../../mytest/spiTest/bench.lst ../../mytest/spiTest/cphex ../../mytest/spiTest/makefile ../../mytest/spiTest/makefile.defines ../../mytest/spiTest/rom.hex ../../mytest/spiTest/rom_if.hex .
cp $f5 .
+ cp '../../mytest/spiTest/*.{v,sv,svh}' .
cp: cannot stat `../../mytest/spiTest/*.{v,sv,svh}': No such file or directory
答案 0 :(得分:4)
检查脚本的第一行。它可能是:
#!/bin/sh
将shell从BASH切换到Bourne Shell。使用
#!/bin/bash
代替。
[编辑] 您遇到了扩展问题。 BASH有一定的顺序,可以扩展模式和变量。这意味着:
f5="$rdir/*.{v,sv,svh}" #testbench files
被引用,因此此时不会发生文件名扩展。仅展开变量$rdir
。当
cp $f5 .
执行后,BASH首先查找要扩展的文件名,但没有。然后它展开变量(f5
),然后使用两个参数调用cp
:../../mytest/spiTest/*.{v,sv,svh}
和.
。由于cp
期望shell已经执行了文件名扩展,因此会出现错误。
要解决此问题,您必须使用数组:
f5=($rdir/*.{v,sv,svh})
这将替换变量,然后展开文件名并将所有内容放入数组f5
中。然后,您可以使用此数组调用cp
,同时保留空格:
cp "${f5[@]}" .
这里的每个角色都很重要。 [@]
告诉BASH在这里扩展整个数组。引述说:保留空白。 {}
必须告诉BASH [@]
是要扩展的变量“name”的一部分。
答案 1 :(得分:4)
问题在于:替换的顺序。 Bash在变量扩展之前执行大括号扩展。在第cp $f5 .
行中,bash将执行:
cp ../../mytest/spiTest/*.{v,sv,svh} .
.{v,sv,svh}
。它找不到,nullglob
未设置,因此模式不会从命令现在命令已执行并因您看到的错误而失败。
https://www.gnu.org/software/bash/manual/bashref.html#Shell-Expansions
解决方案:
eval cp $f5 .
答案 2 :(得分:1)
该行
f5="$rdir/*.{v,sv,svh}" #testbench files
可能是错的。首先,避免在行尾注释,它们应该(至少为了可读性)在一个单独的行中。然后,避免在变量赋值中使用globbing。因此,请删除该行,然后再编码(即将旧的cp $f5 .
行替换为
cp "$rdir"/*.{v,sv,svh} .
顺便说一句,我会测试"$rdir"
确实是一个带的目录
if [ ! -d "$rdir" ] ; then
echo invalid directory $rdir > /dev/stderr
exit 1
fi