为什么Linux命令CP在CLI和脚本中的行为有所不同?

我想复制一堆Verilog / systemverilog源代码,所以我使用CP和通配符表达式:

cp <some_dir>/*.{v,sv,svh} .

有用.但是当我将它放到具有完全相同行的脚本时,CP命令会失败并显示日志:

cp: cannot stat `../../mytest/spiTest/*.{v,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,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,svh}" #testbench files
+ f5='../../mytest/spiTest/*.{v,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,svh}' .
cp: cannot stat `../../mytest/spiTest/*.{v,svh}': No such file or directory

解决方法

检查脚本的第一行.它可能是:

#!/bin/sh

它将shell从BASH切换到Bourne Shell.使用

#!/bin/bash

代替.

[编辑]你遇到了扩展问题. BASH有一定的顺序,可以扩展模式和变量.这意味着:

f5="$rdir/*.{v,svh}" #testbench files

引用,因此此时不会发生文件名扩展.仅展开变量$rdir.什么时候

cp $f5 .

执行后,BASH首先查找要扩展的文件名,但没有.然后它扩展变量(f5)然后用两个参数调用cp:../../ mytest / spiTest / *.{v,svh}和..因为cp要求shell已经执行了文件名扩展,你得到一个错误.

解决此问题,您必须使用数组:

f5=($rdir/*.{v,svh})

这将替换变量,然后展开文件名并将所有内容放入数组f5中.然后,您可以使用此数组调用cp,同时保留空格:

cp "${f5[@]}" .

这里的每一个角色都很重要. [@]告诉BASH在这里扩展整个数组.引述说:保留空白. {}必须告诉BASH [@]是要扩展的变量“name”的一部分.

相关文章

在Linux系统中,设置ARP防火墙可以通过多种方法实现,包括使...
在Linux环境下,使用Jack2进行编译时,可以采取以下策略来提...
`getid`命令在Linux系统中用于获取当前进程的有效用户ID(EU...
在Linux环境下,codesign工具用于对代码进行签名,以确保其完...
Linux中的`tr`命令,其英文全称是“transform”,即转换的意...
Linux中的ARP防火墙是一种用于防止ARP欺骗攻击的安全措施,它...