Shell脚本中.(点/source)命令引用文件的路径规则相关疑问
核心逻辑:三个「点」是完全独立的语法规则
你混淆的核心原因是把三个不同场景下的「.」的规则混在了一起,先明确区分:
- 【通配符场景的
.】:你引用的书中内容说的是这个场景:POSIX 通配符规则里.确实没有特殊含义,仅作为普通字符匹配文件名里的点,只有出现在文件名开头的时候代表隐藏文件。这套规则只在 Shell 做通配符展开的时候生效,和其他场景的「.」无关。 - 【路径解析场景的
.】:Shell 解析文件路径时,单独出现的.固定代表当前工作目录,..代表上级目录,这套规则和通配符规则完全独立,互不影响。 - 【点命令
.的搜索规则】:作为命令的.(等价于source),搜索目标文件的逻辑遵循 POSIX 规范:- 如果传入的文件名参数包含路径分隔符
/,则直接按照给定的路径查找文件,不会搜索$PATH - 如果传入的文件名参数不包含
/,则只会在$PATH环境变量列出的所有路径中依次搜索该文件
- 如果传入的文件名参数包含路径分隔符
你的测试现象逐一解释
1. 为什么交互式命令行执行. file1.sh能成功?
你使用的交互式 Shell(大概率是 Bash)默认会有两个特性:
- 部分用户/发行版会默认把当前目录
.加入到交互式 Shell 的$PATH中 - 即使
$PATH里没有.,Bash 的点命令实现如果在$PATH里找不到文件,会额外尝试在当前工作目录搜索(这是 Bash 对 POSIX 规范的扩展)
所以你在命令行直接执行. file1.sh能匹配到当前目录的文件。
2. 为什么脚本里写. file1.sh执行./file2.sh会报错?
执行./file2.sh时会启动一个非交互式的子 Shell,这个环境下:
- 子 Shell 的
$PATH默认不会包含当前工作目录. - 非交互式 Shell 会严格遵循 POSIX 规范,不会额外搜索当前目录
此时点命令的参数file1.sh不带/,只会去$PATH里找,自然找不到,就会抛出「file not found」的报错。
3. 为什么用. file2.sh执行就不会报错?
这种执行方式是把file2.sh放到你当前的交互式 Shell里执行,用的是交互式 Shell 的环境和搜索规则,自然能找到file1.sh,不会报错。
4. 为什么改成. ./file1.sh之后所有场景都正常?
参数./file1.sh里包含路径分隔符/,触发了点命令的第一条规则:直接按路径查找,不需要搜索$PATH,不管是交互式还是非交互式 Shell,都会直接找当前目录下的file1.sh,所以所有执行方式都能成功。
补充说明
你后续的猜测是对的:你引用的书中那段内容讨论的是通配符和文件扩展名的逻辑,和路径里的.、点命令的规则完全无关,二者不会互相冲突。
内容的提问来源于stack exchange,提问作者adam.hendry
相关产品推荐
相关产品推荐

