![参数可以包含元字符吗?](https://linux22.com/image/218553/%E5%8F%82%E6%95%B0%E5%8F%AF%E4%BB%A5%E5%8C%85%E5%90%AB%E5%85%83%E5%AD%97%E7%AC%A6%E5%90%97%EF%BC%9F.png)
有没有一种方法可以使a中提到的论点手动命令在概要的描述中(我引用“斜体文本替换为适当的参数。”)包含元字符而不转义它?人们会说,从汤姆·莱德(Tom Ryder)中提到的论证的定义来看Bash 快速入门指南(ISBN 978-1-78953-408-5,第 21 页),元字符划分参数(至少对于空格),但在 bash 脚本中,我看到例如左方括号和右方括号的使用方式就像我所说的那样,它们是论证的一部分。例如这个脚本:NUMBER='^[0-9]+$'
.
答案1
我认为“元字符”是一个有点模糊的术语。
Bash 的手册页确实给出了它严格的含义:
元字符:未加引号时用于分隔单词的字符。以下之一:
| & ; ( ) < >
空格制表符换行符”
因此,如果您的意思是,并且传递给从 shell 启动的命令的参数,那么答案宁愿直接是“否”,仅基于定义。
另一方面,有时该词也用于其他特殊字符。如果您包含全局字符(例如[]*?
)或类似的{}!#$
有时很特殊的东西,那么答案可能是“有时”。
具体来说,如果没有与该 glob 模式匹配的文件,ls blahblah?*[123].txt
默认情况下,在类似 POSIX 的 shell 中,将使用参数进行调用ls
。blahblah?*[123].txt
(如果有,它们的名称将被扩展。并且 zsh 和 csh 只会抱怨,除非另有要求)并且 while 在{
支持它的 shell 中开始大括号扩展,只有当单词的其余部分也符合大括号的语法时才特殊扩张。ls {
只传递单个参数{
,但ls foo{a,b}
传递两个参数fooa
, foob
。并且$
可能会也可能不会触发一些扩展,这取决于之后发生的情况。echo foo$
打印foo$
,但echo foo<
给出错误。
这里的要点是,它们|&;()<>
对于 shell 的词法分析器来说是特殊的,因此在命令行处理过程中会更早地被识别,而*?[]$
只有在命令行最初被划分为单词之后才被识别。!
并且#
有些更特别,因为(如果启用历史扩展和评论),它们会更早地被识别。但它们不是相同意义上的元字符,因为它们在词法分析器阶段没有影响。echo foo! foo#
印刷foo! foo#
。
那[[
?这只是一个看起来很奇怪的关键字,类似于等等if
。while
或者确实是{
。 (尝试type if
,,type {
。type [[
)它是一个影响其内部解析的关键字,但它不是由元字符组成,echo [[
仍然打印[[
。与 比较一下((
,哪里echo ((
有错误。 (并且type ((
不起作用,并且type "(("
没有提供任何有用的东西)
不过,我不确定它是否太有用而不能太深入地了解 shell 的语法,它很复杂,而且里面的味道有点奇怪。另外,我可能在上述术语或其他方面犯了错误。