脚本需执行权限才能用 ./ 运行,而 source 不需要;前者启动子进程且环境变更不保留,后者在当前 shell 执行且影响立即生效。

脚本要有执行权限才能用 ./script.sh 方式运行,而 source script.sh(或 . script.sh)不需要执行权限,它只是在当前 shell 环境中逐行读取并执行文件内容。
执行权限的作用与设置方法
执行权限(如 x 位)是操作系统对文件能否被当作程序“启动”的安全控制。Shell 脚本本质是文本文件,只有被赋予执行权限后,内核才允许将其作为独立进程加载运行(通过 execve() 系统调用)。
- 查看权限:用
ls -l script.sh,看到类似-rw-r--r--表示无执行权;-rwxr-xr-x表示有 - 添加权限:运行
chmod +x script.sh(给所有用户加 x 权限),或更精确地chmod u+x script.sh(仅给文件所有者加) - 去掉权限:用
chmod -x script.sh - 注意:即使有执行权限,脚本第一行的
#!/bin/bash(shebang)也必须正确,否则可能报错或用错误解释器执行
Source 命令不依赖执行权限的原因
source 不是“运行脚本”,而是让当前 shell 解析并执行该文件中的命令——相当于把文件内容复制粘贴到当前终端里手动敲一遍。它不触发新进程,也不经过内核的执行权限检查。
- 等价写法:
source script.sh和. script.sh完全相同(点号是 source 的 POSIX 别名) - 变量和函数定义会留在当前 shell:比如脚本里写了
export PATH=$PATH:/my/bin,source 后当前终端就能用;而直接./script.sh执行完就失效 - 只要文件有读权限(
r),source 就能工作;没有读权限会提示Permission denied,和执行权限无关
两种方式的本质差异对比
关键区别在于是否创建子 shell 进程,以及作用域是否隔离:
-
./script.sh:启动一个新 bash 进程(子 shell),脚本在其中运行;环境变量、cd 切换目录、函数定义等都只在子进程中生效,退出后全部丢失 -
source script.sh:在当前 shell 中直接执行,所有变更立即影响当前环境;适合配置环境变量、定义别名、加载函数库等场景 - 调试建议:想确认某段逻辑是否影响当前环境,优先用 source;想测试脚本是否可独立运行,必须加执行权限后用 ./ 方式
常见误操作与排查提示
遇到“Permission denied”时,先分清是哪种调用方式再定位问题:
- 报错
bash: ./script.sh: Permission denied→ 检查执行权限是否缺失(chmod +x) - 报错
bash: script.sh: Permission denied(没加 ./)→ 可能是当前目录不在$PATH,且没用绝对/相对路径调用;但更可能是文件真的没读权限 - source 后变量没生效?检查脚本里是否用了
export(普通变量赋值不会自动导出到环境) - 脚本里用了
exit:在 source 场景下会导致当前 shell 直接退出,要特别小心










