为何Wildcards可作为Shell参数使用?结合ls实例解析疑问
为什么通配符能作为Shell命令的参数?
这其实是Shell的文件名扩展(Filename Expansion)(也常叫通配符展开)在幕后起作用,根本不是ls这类命令自己在处理通配符哦!
核心逻辑:Shell先“翻译”通配符,再传给命令
当你在终端输入带通配符的命令时,Shell会先执行以下步骤,再把处理后的结果传给目标命令:
- 识别命令行里的通配符模式(比如你用的
/[!\(][!\(][!\(]/) - 根据Shell的通配符规则,在对应目录下查找所有匹配的文件/目录
- 把匹配到的实际路径替换掉原来的通配符字符串,作为参数传给后续命令
针对你的ls例子拆解
你输入的命令是ls /[!\(][!\(][!\(]/,Shell会先做这些操作:
- 解析通配符模式:
/[!\(][!\(][!\(]/要匹配**根目录下名称为3个字符、且每个字符都不是左括号(**的目录(末尾的/是专门用来限定只匹配目录的) - Shell遍历根目录下的所有条目,找出符合条件的目录,比如
/bin/、/usr/、/var/这些 - 然后Shell把这些具体的目录路径作为参数传给
ls,ls接收到的是/bin/ /usr/ /var/ ...,而不是原来的通配符字符串 - 最后
ls会依次列出每个目录下的内容,这就是你看到的那一大串输出啦
额外提醒:通配符≠正则表达式
别把Shell的通配符和正则表达式搞混:
- Shell用的是文件名通配符规则:比如
*匹配任意长度的任意字符,[]匹配字符集中的单个字符,[!...]排除指定字符 - 正则表达式是另一套匹配语法,通常在
grep、sed、awk这类文本处理工具里使用,和Shell的通配符规则完全不同
另外,如果某个命令需要自己处理通配符(比如find -name),你需要用单引号把通配符括起来,避免Shell提前展开它。
内容的提问来源于stack exchange,提问作者user2147674
相关产品推荐
相关产品推荐

