关于临时变量的解析和操作

一、什么是临时变量?

临时变量:只在当前Shell会话或脚本中存在的变量,会话结束或脚本执行完毕自动销毁。

二、完整的临时变量脚本

#!/bin/bash
# 文件名: temp_variables_demo.sh
# 功能: 演示Shell中各种临时变量的使用

echo "========== 1. 普通变量(字符串)=========="
name="John Doe"
age=25
echo "姓名: $name"
echo "年龄: $age"
echo "年龄(另一种写法): ${age}"

echo -e "\n========== 2. 命令替换 =========="
current_date=$(date +%Y-%m-%d)
current_time=`date +%H:%M:%S`  # 旧式写法
files_count=$(ls | wc -l)
echo "当前日期: $current_date"
echo "当前时间: $current_time"
echo "文件数量: $files_count"

echo -e "\n========== 3. 算术运算 =========="
a=10
b=3
sum=$((a + b))
diff=$((a - b))
product=$((a * b))
quotient=$((a / b))
remainder=$((a % b))
power=$((a ** 2))
echo "a=$a, b=$b"
echo "加法: $sum"
echo "减法: $diff"
echo "乘法: $product"
echo "除法: $quotient"
echo "取余: $remainder"
echo "平方: $power"
echo "复合运算: $((a + b * 2))"

echo -e "\n========== 4. 数组变量 =========="
# 普通数组
fruits=("apple" "banana" "orange" "grape")
echo "第一个水果: ${fruits[0]}"
echo "所有水果: ${fruits[@]}"
echo "水果数量: ${#fruits[@]}"

# 关联数组(需要声明)
declare -A person
person=(
    [name]="张三"
    [age]=30
    [city]="北京"
    [job]="工程师"
)
echo "姓名: ${person[name]}"
echo "年龄: ${person[age]}"
echo "城市: ${person[city]}"
echo "职业: ${person[job]}"

echo -e "\n========== 5. 只读变量 =========="
readonly PI=3.14159
readonly GRAVITY=9.8
echo "圆周率: $PI"
echo "重力加速度: $GRAVITY"
# PI=3.14  # 这行会报错,只读变量不能修改

echo -e "\n========== 6. 局部变量 =========="
function test_local() {
    local local_var="我是局部变量"
    global_var="我是全局变量"
    echo "函数内部 - $local_var"
    echo "函数内部 - $global_var"
}
test_local
echo "函数外部 - $global_var"  # 可以访问
# echo "函数外部 - $local_var" # 不能访问(已注释)

echo -e "\n========== 7. 环境变量 =========="
export MY_APP_HOME="/opt/myapp"
export MY_APP_VERSION="1.0.0"
echo "应用目录: $MY_APP_HOME"
echo "应用版本: $MY_APP_VERSION"
echo "当前用户: $USER"
echo "当前目录: $PWD"
echo "家目录: $HOME"
echo "Shell路径: $SHELL"
echo "系统路径: $PATH"

echo -e "\n========== 8. 特殊变量 =========="
echo "脚本名: \$0 = $0"
echo "第一个参数: \$1 = $1"
echo "第二个参数: \$2 = $2"
echo "所有参数: \$@ = $@"
echo "参数个数: \$# = $#"
echo "当前PID: \$$ = $$"
echo "上一个命令退出码: \$? = $?"
echo "当前选项: \$- = $-"

echo -e "\n========== 9. 变量默认值 =========="
unset unset_var
null_var=""
set_var="我有值"

echo "未设置变量: ${unset_var:-默认值}"
echo "空字符串: ${null_var:-默认值}"
echo "有值变量: ${set_var:-默认值}"
echo "未设置变量赋值: ${unset_var:=新值}"  # 同时赋值
echo "现在unset_var的值: $unset_var"

echo -e "\n========== 10. 变量字符串操作 =========="
str="Hello World from Shell"
echo "原字符串: $str"
echo "长度: ${#str}"
echo "从第7位开始: ${str:6}"
echo "从第6位取5个字符: ${str:6:5}"
echo "删除前缀#Hello#: ${str#Hello}"
echo "删除后缀#Shell#: ${str%Shell}"
echo "替换World为Linux: ${str/World/Linux}"
echo "转大写: ${str^^}"
echo "转小写: ${str,,}"

echo -e "\n========== 11. 类型声明 =========="
declare -i int_var=10    # 整数类型
declare -r readonly_var="不能改"  # 只读
declare -l lower_var="HELLO"  # 自动转小写
declare -u upper_var="world"  # 自动转大写
declare -a array_var=(1 2 3)  # 数组
declare -A map_var=([key]=value)  # 关联数组

echo "整数变量: $int_var"
echo "小写变量: $lower_var"
echo "大写变量: $upper_var"

echo -e "\n========== 12. 间接变量 =========="
var_name="current_user"
current_user="root"
echo "间接引用: ${!var_name}"  # 输出 root

echo -e "\n========== 13. 变量导出到子进程 =========="
export EXPORTED_VAR="我可以传给子进程"
bash -c 'echo "子进程看到: $EXPORTED_VAR"'

echo -e "\n========== 14. 变量清除 =========="
temp_var="临时数据"
echo "清除前: $temp_var"
unset temp_var
echo "清除后: ${temp_var:-未定义}"

echo -e "\n========== 15. 测试完毕 =========="

临时变量类型解析表

变量类型声明方式作用域生命周期示例说明
普通变量var=value当前Shell会话结束name="John"最基础,无空格可直接赋值
命令替换$(cmd)`cmd`当前Shell命令执行完date=$(date)将命令输出赋给变量
算术变量$((expr))当前Shell计算完sum=$((a+b))支持+ – * / % **等运算
数组变量arr=(v1 v2)当前Shell会话结束fruits=(apple orange)下标从0开始
关联数组declare -A map当前Shell会话结束person=([name]=张三)键值对形式
只读变量readonly var当前Shell会话结束readonly PI=3.14定义后不能修改
局部变量local var函数内函数结束local temp="test"只在函数内有效
环境变量export var当前及子进程会话结束export PATH=/usr/bin子进程可以继承
特殊变量$0, $1, $@当前脚本脚本结束echo $#Shell预定义的特殊含义
位置参数$1, $2, $3...当前脚本脚本结束echo $1脚本传入的参数
默认值变量${var:-default}当前Shell临时echo ${name:-匿名}变量未定义时用默认值
字符串变量普通赋值当前Shell会话结束${#str}支持各种字符串操作

变量操作速查表

操作语法示例结果
赋值var=valuename="Tom"name=Tom
引用$var${var}echo $nameTom
长度${#var}${#name}3
切片${var:start:len}${name:0:2}To
删除前缀${var#pattern}${name#T}om
删除后缀${var%pattern}${name%m}To
替换${var/old/new}${name/o/a}Tam
转大写${var^^}${name^^}TOM
转小写${var,,}${name,,}tom
默认值${var:-default}${age:-18}18(如果age未定义)
赋值默认${var:=default}${age:=18}设置age=18
错误检查${var:?错误}${age:?未定义}报错并退出
存在检查${var:+存在}${name:+有值}有值(如果name存在)

实战示例

# 保存为实战脚本并执行
cat > practice.sh << 'EOF'
#!/bin/bash

# 1. 配置文件读取
CONFIG_FILE="${1:-/etc/myapp.conf}"
echo "使用配置文件: $CONFIG_FILE"

# 2. 日志记录
LOG_DIR="/var/log/myapp"
LOG_FILE="${LOG_DIR}/app_$(date +%Y%m%d).log"
echo "日志文件: $LOG_FILE"

# 3. 临时文件
TEMP_FILE="/tmp/temp_$$.txt"
echo "临时文件: $TEMP_FILE"

# 4. 数组循环
SERVERS=("web1" "web2" "db1" "cache1")
echo "服务器列表: ${SERVERS[@]}"
for server in "${SERVERS[@]}"; do
    echo "处理: $server"
done

# 5. 函数局部变量
process_file() {
    local filename="$1"
    local filesize=$(ls -l "$filename" 2>/dev/null | awk '{print $5}')
    echo "文件 $filename 大小: ${filesize:-0} bytes"
}

# 6. 环境变量检查
: ${JAVA_HOME:?"请设置JAVA_HOME环境变量"}

# 7. 清理临时文件
cleanup() {
    rm -f "$TEMP_FILE"
    echo "清理完成"
}
trap cleanup EXIT

echo "脚本执行完成"
EOF

chmod +x practice.sh
./practice.sh

关键点总结

  1. 作用域:普通变量只在当前Shell,export后到子进程
  2. 生命周期:临时变量随会话或脚本结束而销毁
  3. 命名规则:字母、数字、下划线,不能以数字开头
  4. 引用方式$var${var}(后者更安全)
  5. 默认值${var:-default} 是常用技巧
  6. 只读变量:定义后不能修改,适合常量
  7. 局部变量:函数内用 local 声明,避免污染全局

这些临时变量是Shell编程的基础,掌握它们就能写出强大的脚本!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注