通配符是在Shell还是其派生命令中展开?附实操场景验证
执行
ls *.txt时的底层过程 结论很明确:是Shell先把*.txt展开成匹配的文件名列表,再把完整的参数传给ls进程,而非让ls自己处理*.txt这个通配符。
具体的底层步骤拆解:
- 当你在Shell里敲完
ls *.txt回车后,Shell首先会对命令行做解析,识别出*.txt是路径名通配符(属于Shell的"路径扩展"功能)。 - Shell会遍历当前工作目录下的所有文件,筛选出文件名以
.txt结尾的文件——也就是demo.txt、text.txt、temp.txt这三个。 - 接下来Shell会把原命令中的
*.txt替换成这三个文件名,构建出最终的参数列表:argv数组里依次是"ls"、"demo.txt"、"text.txt"、"temp.txt",最后以空指针收尾。 - 然后Shell通过
fork()系统调用创建一个子进程,接着在子进程里调用execve()(或其他exec系列函数),把刚才构建好的参数列表传递给新进程,新进程会加载并执行ls程序。 ls程序启动后,直接读取传入的argv参数,拿到三个具体的文件名,然后执行对应的文件列表输出逻辑。
你可以用几个小实验验证这个逻辑:
- 执行
echo *.txt,会直接输出demo.txt text.txt temp.txt,说明是Shell完成了通配符展开,echo只是把收到的参数打印出来。 - 执行
ls '*.txt'(用单引号把通配符括起来),Shell会把*.txt当作普通字符串处理,不会展开,这时候ls会去查找名为*.txt的文件,自然会报错ls: cannot access '*.txt': No such file or directory,这也反过来证明了通配符展开是Shell的工作,而非ls的功能。
内容的提问来源于stack exchange,提问作者laplacedoge
相关产品推荐
相关产品推荐

