Unix/Linux中的 dot 命令(.)是一个内置的Shell命令,用于在当前Shell环境中执行脚本。
基本语法
. filename [arguments]
或(等价写法)
source filename [arguments]
核心特性
1. 在当前Shell中执行
与直接执行脚本(./script.sh)不同,点命令不会创建子进程:
- 脚本中的变量、函数、别名等会直接影响当前Shell环境
- 脚本中的
cd命令会改变当前工作目录
- 脚本退出后,环境变化仍然保留
2. 搜索路径
- 如果文件名不包含斜杠(
/),Shell会在$PATH中查找
- 如果文件名以
./开头,则使用当前目录的文件
- 相对路径(如
../config.sh)和绝对路径也可用
常见用途
1. 加载配置文件
# 重新加载bash配置文件
. ~/.bashrc
source ~/.bash_profile
# 加载环境变量
. /etc/profile
. env.sh
2. 定义函数和别名
# myfuncs.sh 内容:
myfunc() {
echo "Hello $1"
}
alias ll='ls -la'
# 加载后可直接使用
. myfuncs.sh
myfunc "World" # 输出: Hello World
ll # 执行 ls -la
3. 设置环境变量
# config.sh 内容:
export JAVA_HOME=/usr/lib/jvm/java-11
export PATH="$JAVA_HOME/bin:$PATH"
# 加载到当前Shell
. config.sh
echo $JAVA_HOME # 输出: /usr/lib/jvm/java-11
与直接执行脚本的区别
| 特性 |
. script.sh |
./script.sh 或 bash script.sh |
|---|
| 执行环境 |
当前Shell |
新建子Shell |
| 环境变量 |
影响当前Shell |
不影响当前Shell |
cd命令 |
改变当前目录 |
不影响当前目录 |
| 退出状态 |
最后执行的命令的退出码 |
脚本的退出码 |
| 需要的权限 |
只需要读权限 |
需要读和执行权限 |
示例演示
示例1:环境变量持久化
# 创建 testenv.sh
echo 'export MY_VAR="test value"' > testenv.sh
# 方法1:点命令(变量保留)
. testenv.sh
echo $MY_VAR # 输出: test value
# 方法2:子进程执行(变量不保留)
bash testenv.sh
echo $MY_VAR # 输出: (空或之前的值)
示例2:改变工作目录
# createdir.sh 内容:
mkdir -p /tmp/testdir
cd /tmp/testdir
pwd
# 使用点命令
. createdir.sh # 输出: /tmp/testdir
pwd # 输出: /tmp/testdir (目录已改变)
# 使用子进程执行
bash createdir.sh # 输出: /tmp/testdir
pwd # 输出: 原目录(未改变)
注意事项
安全性:点命令会执行脚本中的所有命令,需确保脚本来源可信
错误处理:脚本中的错误会影响当前Shell环境
返回值:返回最后一条命令的退出状态码
参数传递:可以向脚本传递参数,通过
$1、
$2等访问
最佳实践
配置文件:使用点命令加载配置
函数库:将常用函数放在单独文件,用点命令导入
环境设置:项目相关的环境变量用点命令设置
避免污染:在脚本开头使用
set -e等设置仅影响脚本执行
常见问题
Q: . 和 source 有什么区别?
A: 在bash中完全相同,source是.的同义词。但某些Shell(如dash)可能不支持source。
Q: 如何检查脚本是否被点命令执行?
A: 可以检查$0变量:
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
echo "直接执行"
else
echo "被source/.执行"
fi
Q: 点命令执行的脚本需要执行权限吗?
A: 不需要,只需要读权限。因为Shell直接读取并解释文件内容。
这个命令在Shell编程和系统管理中非常有用,特别是在设置开发环境、管理配置等方面。