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}:变量为空时使用默认值并赋值

常见问题与排错#

  1. 变量未赋值或为空
    - 现象:输出为空,逻辑判断失败
    - 排查:set -u 可捕捉未定义变量
    - 修复:使用 ${var:-default} 或确保赋值

  2. 路径包含空格导致命令失败
    - 现象:cp $path /tmp 报错“无法找到文件”
    - 修复:cp "$path" /tmp

  3. 通配符误匹配
    - 现象:rm $files 删除了更多文件
    - 修复:rm -- "$files" 或数组保存文件列表

练习#

  1. 编写脚本 /opt/scripts/userinfo.sh,接收用户名参数 $1,输出:
    - 用户名
    - 当前时间(使用命令替换)
    - 若参数为空,默认输出 guest
  2. 将路径变量设置为 /tmp/test dir,分别用单引号、双引号、无引号输出,观察差异并记录结果。
  3. 使用 ${var:=value} 给未定义变量赋值并验证在后续命令中是否生效。