使用source与直接执行Shell脚本的异常行为及原因问询
两种Shell脚本执行方式的区别与输出差异原因
一、核心执行方式差异
- 直接执行:启动新的子Shell进程运行脚本,脚本拥有独立的执行环境,参数传递完全由父Shell按字面意义传递,子Shell自行解析。
- source/
.执行:脚本在当前Shell进程中直接运行,共享当前Shell的所有环境变量、解析规则和位置参数,参数解析受当前Shell的设置影响。
二、输出差异的具体原因
你的脚本通过${flag//=/ }将参数中的=替换为空格,再用for循环遍历内容,差异源于参数解析和扩展的行为不同:
直接执行时的行为
运行./test.sh -p=test:
- 父Shell将
-p=test作为完整的单一参数传递给子Shell,脚本中flag="$1"的值为-p=test。 ${flag//=/ }将=替换为空格,得到-p test。由于该扩展结果未被引号包裹,子Shell按默认IFS(空格、制表符、换行)拆分字符串,for循环遍历-p和test两个元素,因此输出两行结果。
source执行时的行为
运行source ./test.sh -p=test:
- 当前Shell在解析命令行参数时,将
-p=test解析为包含空格的单一字符串-p test(这是因为当前Shell的命令行解析逻辑将=视为隐含的空格分隔符,常见于部分Shell的补全或参数解析规则)。 - 脚本中
flag="$1"的值为-p test,由于字符串中没有=,${flag//=/ }替换后内容不变。此时for循环遍历这个未被拆分的单一元素,因此只输出一行结果。
即使切换到/bin/bash或/bin/sh,这种差异仍然存在,因为不同Shell的命令行解析规则在处理带=的参数时,对于source执行的场景会有不同的处理逻辑,而直接执行时子Shell的解析规则是统一的。
内容的提问来源于stack exchange,提问作者jlim
相关产品推荐
相关产品推荐

