shell 脚本中的代码段
fname=$(sed 's/(.*//' <<< $p | awk '{ print $NF }')
if [[ $fname == *['!'@#\$%^\&*()_+]* ]]
then
flag1=0
fi
其中 $p 是文本文件中的一行。
p 值为 >= (short)BigBlock * DISK_SIZE + Size)
当对 p 值执行上述 shell 脚本时,它会给出垃圾结果,例如出现在终端上
>= (short)BigBlock file1 file2 file3 DISK_SIZE + Size)
其中 file1 file2 file3 是文件夹中的文件
我的猜测是 * 被视为 ls 命令
可能的解决方案是什么
答案1
摘要: 您echo $p
的代码中可能有这样的地方。您需要双引号$p
。
不,*
不被视为ls
命令。然而,由于在某处不加引号地使用(不在问题中显示的代码中),它被视为文件名通配模式
在分配和使用 的值时需要小心,p
并使用适当的引号来保护字符串。
文件名通配模式不会在此处字符串中扩展:
$ cat <<< *
*
$p
因此,在调用中使用不带引号的 没有任何问题sed
。然而,显式引用变量扩展几乎总是更好。另请参阅$fname
测试中未引用的使用。这肯定应该加双引号。
你说脚本输出文本
>= (short)BigBlock file1 file2 file3 DISK_SIZE + Size)
没有什么会引起该字符串在问题中显示的脚本中输出。这可能是由于你做的
echo $p
脚本中的其他地方。
再次,在 周围使用双引号$p
:
echo "$p"
这样,您就可以阻止 shell 对其值执行文件名通配(扩展*
)。
一般来说,echo
仅用于静态字符串,用于printf
可变数据:
printf '$p is "%s"\n' "$p"
与最后一点相关:为什么 printf 比 echo 更好?
答案2
首先,在等待真正的 $p 值字符串时:确保引用 $p。
fname=$(sed 's/(.*//' <<< "$p" | awk '{ print $NF }')
另请注意,sed 's/(.*//'
将匹配字符串的末尾。
f='(something) and more stuff';sed 's/(.*//' <<< "$f"
结果当然是空字符串。
f='(something)-and more stuff';sed 's/([^)]*)//' <<< "$f"
结果: - 以及更多内容