变量是脚本的基本组成单位。Shell 的变量机制简单灵活,但也有容易踩坑的地方。
Shell 定义变量很简单,不需要声明类型:
NAME="张三"
AGE=25
PATH="/usr/local/bin"
注意几点:
# 错误写法
NAME = "张三" # 等号两边有空格
1VAR="test" # 以数字开头
# 正确写法
NAME="张三"
_VAR="test"
使用变量要加 $ 符号:
NAME="张三"
echo $NAME
echo ${NAME} # 推荐用花括号,更清晰
花括号在变量拼接时特别有用:
APP="myapp"
echo $APP_server # 变量名是 APP_server,不是 APP
echo ${APP}_server # 变量名是 APP,输出 myapp_server
用 readonly 声明只读变量:
PI=3.14
readonly PI
PI=3.14159 # 报错:PI: readonly variable
用 unset 删除变量:
NAME="张三"
unset NAME
echo $NAME # 输出空
注意 unset 不能删除只读变量。
Shell 变量按作用域分三类:
局部变量
只在当前脚本或函数内有效:
#!/bin/bash
NAME="张三" # 局部变量
echo $NAME
环境变量
对子进程也有效,用 export 导出:
export JAVA_HOME=/usr/lib/jvm/java-11
./child_script.sh # 子脚本能访问 JAVA_HOME
常见的系统环境变量:
echo $HOME # 用户主目录
echo $PATH # 命令搜索路径
echo $USER # 当前用户
echo $PWD # 当前目录
echo $SHELL # 当前 Shell
特殊变量
Shell 预定义的特殊变量:
$0 # 脚本名称
$1-$9 # 第1到第9个参数
$# # 参数个数
$@ # 所有参数(作为独立字符串)
$* # 所有参数(作为单个字符串)
$? # 上一个命令的退出码
$$ # 当前进程 PID
$! # 后台运行的最后一个进程 PID
示例:
#!/bin/bash
echo "脚本名: $0"
echo "第一个参数: $1"
echo "参数个数: $#"
echo "所有参数: $@"
# 运行
./test.sh a b c
# 脚本名: ./test.sh
# 第一个参数: a
# 参数个数: 3
# 所有参数: a b c
变量可能为空,设置默认值避免出错:
# 如果 VAR 为空,使用默认值
echo ${VAR:-default}
# 如果 VAR 为空,赋值并使用
echo ${VAR:=default}
# 如果 VAR 为空,报错退出
echo ${VAR:?错误:变量未设置}
# 如果 VAR 非空,使用替代值
echo ${VAR:+替代值}
实际应用:
#!/bin/bash
# 备份脚本,可指定备份目录
BACKUP_DIR=${1:-/backup} # 第一个参数或默认 /backup
echo "备份目录: $BACK_DIR"
函数内的变量默认是全局的:
#!/bin/bash
test_func() {
VAR="hello" # 这也是全局变量
}
test_func
echo $VAR # 输出 hello
用 local 声明局部变量:
#!/bin/bash
test_func() {
local VAR="hello" # 局部变量
echo "函数内: $VAR"
}
test_func
echo "函数外: $VAR" # 输出空
# 方式一:反引号(旧写法)
DATE=`date +%Y%m%d`
# 方式二:$()(推荐)
DATE=$(date +%Y%m%d)
USER_NAME=$(whoami)
#!/bin/bash
echo -n "请输入名字: "
read NAME
echo "你好, $NAME"
# 简化写法
read -p "请输入名字: " NAME
echo "你好, $NAME"
变量使用要点:
$,推荐用 ${}local 声明局部变量