5.1.3 变量与引号基础
变量与引号是 Shell 脚本的最小单元,决定了参数传递、字符串拼接与命令输出的可靠性。本节通过原理示意、完整示例、排错与练习,帮助建立可控的变量使用习惯。
变量定义与引用规则#
- 变量名:字母/数字/下划线,不能以数字开头
- 赋值:等号两侧不能有空格
- 引用:推荐统一使用
${var}形式
示例(可直接执行):
#!/usr/bin/env bash
# file: /opt/scripts/var_demo.sh
set -e
name=linux
role=ops
echo "name=${name}"
echo "拼接: ${name}_${role}"
# 位置参数示例
echo "脚本名: $0"
echo "第1个参数: $1"
echo "参数个数: $#"
执行与预期效果:
chmod +x /opt/scripts/var_demo.sh
/opt/scripts/var_demo.sh hello
预期输出:
name=linux
拼接: linux_ops
脚本名: /opt/scripts/var_demo.sh
第1个参数: hello
参数个数: 1
引号行为与命令替换#
- 单引号
'...':禁止变量与转义解析 - 双引号
"...":解析变量/命令替换,保留空格 - 无引号:词分割 + 通配符展开(高风险)
- 命令替换:
$(...)推荐替代反引号
示例对比(包含空格与通配符):
#!/usr/bin/env bash
# file: /opt/scripts/quote_demo.sh
set -e
file_path="/tmp/demo file.txt"
mkdir -p /tmp
touch "/tmp/demo file.txt"
echo '单引号: $file_path'
echo "双引号: $file_path"
echo 无引号: $file_path
echo "命令替换: $(ls /tmp | head -n 1)"
执行与预期效果:
chmod +x /opt/scripts/quote_demo.sh
/opt/scripts/quote_demo.sh
预期输出(关键差异):
单引号: $file_path
双引号: /tmp/demo file.txt
无引号: /tmp/demo file.txt
命令替换: demo file.txt
说明:无引号时若变量包含多个空格或通配符,会被拆分成多个参数,导致命令报错或误操作。
环境变量与局部变量#
环境变量通过 export 传递给子进程,局部变量只在当前 Shell 生效。
#!/usr/bin/env bash
# file: /opt/scripts/env_demo.sh
set -e
local_var=local
export ENV_VAR="from_parent"
bash -c 'echo "子进程看到 ENV_VAR=${ENV_VAR}"; echo "子进程看到 local_var=${local_var}"'
执行与预期效果:
chmod +x /opt/scripts/env_demo.sh
/opt/scripts/env_demo.sh
预期输出:
子进程看到 ENV_VAR=from_parent
子进程看到 local_var=
默认值与健壮性#
使用参数展开防止空值导致逻辑出错:
#!/usr/bin/env bash
# file: /opt/scripts/default_demo.sh
set -e
user=${USER_NAME:-"default_user"}
port=${PORT:=8080} # 未设置时赋值
echo "user=${user}, port=${port}"
执行与预期效果:
chmod +x /opt/scripts/default_demo.sh
/opt/scripts/default_demo.sh
预期输出:
user=default_user, port=8080
关键命令与参数解释#
export VAR=value:将变量导出为环境变量echo "$var":推荐使用双引号避免词分割printf "%s\n" "$var":更可控的输出,避免echo解析差异${var:-default}:变量为空时使用默认值${var:=default}:变量为空时使用默认值并赋值
常见问题与排错#
-
变量未赋值或为空
- 现象:输出为空,逻辑判断失败
- 排查:set -u可捕捉未定义变量
- 修复:使用${var:-default}或确保赋值 -
路径包含空格导致命令失败
- 现象:cp $path /tmp报错“无法找到文件”
- 修复:cp "$path" /tmp -
通配符误匹配
- 现象:rm $files删除了更多文件
- 修复:rm -- "$files"或数组保存文件列表
练习#
- 编写脚本
/opt/scripts/userinfo.sh,接收用户名参数$1,输出:
- 用户名
- 当前时间(使用命令替换)
- 若参数为空,默认输出guest - 将路径变量设置为
/tmp/test dir,分别用单引号、双引号、无引号输出,观察差异并记录结果。 - 使用
${var:=value}给未定义变量赋值并验证在后续命令中是否生效。