参数展开是 Shell 处理变量的核心机制。除了基本的
${var},还有默认值设置、字符串截取、替换、大小写转换等高级用法。熟练掌握参数展开,能让脚本更简洁高效。
name="张三"
echo $name
echo ${name}
${name} 比 $name 更明确,推荐使用。
变量不存在或为空时,返回默认值:
name=${1:-"匿名"}
echo "你好,$name"
port=${PORT:-8080}
echo "端口:$port"
变量不存在或为空时,赋值并返回:
: ${config:="/etc/app.conf"}
echo "配置文件:$config"
: 是空命令,用于执行变量赋值。
变量存在且非空时,返回 value:
debug=${DEBUG:+1}
echo "调试模式:$debug"
变量不存在或为空时,输出错误信息并退出:
: ${API_KEY:?请设置 API_KEY 环境变量}
str="Hello World"
echo ${#str}
运行结果:
11
从 offset 位置开始截取:
str="Hello World"
echo ${str:6}
运行结果:
World
从 offset 位置开始截取 length 个字符:
str="Hello World"
echo ${str:0:5}
echo ${str:6:5}
运行结果:
Hello
World
负数表示从末尾开始:
str="Hello World"
echo ${str: -5}
echo ${str: -5:3}
运行结果:
World
Wor
注意冒号后要有空格。
从开头删除最短匹配:
path="/usr/local/bin/python"
echo ${path#*/}
运行结果:
usr/local/bin/python
从开头删除最长匹配:
path="/usr/local/bin/python"
echo ${path##*/}
运行结果:
python
从末尾删除最短匹配:
file="document.txt.bak"
echo ${file%.*}
运行结果:
document.txt
从末尾删除最长匹配:
file="document.txt.bak"
echo ${file%%.*}
运行结果:
document
file="/home/user/document.txt"
filename=${file##*/}
extension=${file##*.}
basename=${filename%.*}
dir=${file%/*}
echo "文件名:$filename"
echo "扩展名:$extension"
echo "基本名:$basename"
echo "目录:$dir"
替换第一个匹配:
str="hello world world"
echo ${str/world/WORLD}
运行结果:
hello WORLD world
替换所有匹配:
str="hello world world"
echo ${str//world/WORLD}
运行结果:
hello WORLD WORLD
替换开头的匹配:
str="hello world"
echo ${str/#hello/HELLO}
运行结果:
HELLO world
替换末尾的匹配:
str="hello world"
echo ${str/%world/WORLD}
运行结果:
hello WORLD
首字母大写:
str="hello"
echo ${str^}
全部大写:
str="hello"
echo ${str^^}
首字母小写:
str="HELLO"
echo ${str,}
全部小写:
str="HELLO"
echo ${str,,}
匹配前缀的变量名:
PATH1="/usr"
PATH2="/bin"
PATH3="/home"
echo ${!PATH*}
运行结果:
PATH PATH1 PATH2 PATH3
同上,但以数组形式返回。
间接引用:
name="张三"
var="name"
echo ${!var}
运行结果:
张三
arr=(a b c d e)
echo ${arr[0]}
echo ${arr[@]}
echo ${#arr[@]}
echo ${arr[@]:1:3}
echo ${arr[@]/a/A}
file="/data/backup/app_20240315.tar.gz"
filename=${file##*/}
basename=${filename%%.*}
extension=${filename#*.}
dir=${file%/*}
echo "文件名:$filename"
echo "基本名:$basename"
echo "扩展名:$extension"
echo "目录:$dir"
host=${HOST:-localhost}
port=${PORT:-8080}
user=${USER:-$USER}
password=${PASSWORD:?请设置密码}
str=" Hello World "
str=${str# }
str=${str% }
str=${str,,}
str=${str// /_}
echo "$str"
for file in *.txt; do
base=${file%.txt}
mv "$file" "${base}.md"
done
${var:-default} 设置默认值${#var} 获取字符串长度${var:offset:length} 截取子字符串${var#pattern} ${var%pattern} 删除匹配${var/pattern/replacement} 替换匹配${var^^} ${var,,} 大小写转换${!var} 间接引用