脚本声明与执行
- Shebang:
#!/bin/bash
- 执行方式:
- 赋权执行:
chmod +x script.sh -> ./script.sh(开启子进程执行)
- 解释器执行:
bash script.sh(开启子进程执行)
- 当前环境执行:
source script.sh 或 . script.sh(常用于加载配置/环境变量,不开启子进程)
变量参数
| 变量 |
说明 |
示例 |
$0 |
当前脚本的文件名(或 Shell 名称) |
$0 → ./test.sh |
$1 ~ $9 |
第 1 到第 9 个位置参数 |
$1 → a,$2 → b,$3 → c |
${10} |
第 10 个及以上的位置参数(必须使用大括号) |
${10} → 第 10 个参数(若存在) |
$# |
位置参数的总个数(不含 $0) |
$# → 3 |
$@ |
所有位置参数,每个参数作为独立的字符串 |
for arg in "$@" → 依次得到 a、b、c |
$* |
所有位置参数,作为一个整体字符串(首个参数与末个参数之间由 IFS 分隔) |
"$*" 默认 → "a b c"(IFS 首字符为空格) |
$? |
上一条命令的退出状态码 |
ls /tmp; echo $? → 若成功则 0 |
$$ |
当前 Shell 脚本的进程 ID(PID) |
echo $$ → 例如 12345 |
$! |
最近一次放入后台执行的进程 PID |
sleep 10 & echo $! → 输出后台 sleep 命令的 PID |
引号与转义
这是 Bash 解析机制的核心,决定了字符的“字面量”与“替换”行为。
- 反斜杠
\:转义
- 单引号
'':硬引号,原样输出
- 双引号
"":软引号,允许替换
命令替换与算术运算
- 命令替换:将命令的输出结果赋值给变量。
- 推荐写法:
VAL=$(command arg)
- 旧写法:
VAL=`command arg`
- 算术运算:Bash 原生只支持整数运算。
- 推荐写法:
$(( expression )),例如 RESULT=$(( 5 + 3 ))
- 内部变量无需加
$:$(( a + b )) 等同于 $(( $a + $b ))
- 支持运算:
+, -, *, /, %, **
- 支持自增/自减:
(( i++ )), (( i-- )), (( i += 2 ))
字符串操作
| 分类 |
语法 |
说明 |
| 获取长度 |
${#VAR} |
返回变量 VAR 的字符串长度 |
| 提取子串 |
${VAR:offset:length} |
从 offset 位置(从0开始)取 length 个字符 |
| 默认值(不改变变量) |
${VAR:-default} |
若 VAR 未设置或为空,返回 default,但不修改 VAR |
| 默认值(改变变量) |
${VAR:=default} |
若 VAR 未设置或为空,将其赋值为 default 并返回 |
| 替换(首个) |
${VAR/pattern/replacement} |
替换第一个匹配的 pattern |
| 替换(全部) |
${VAR//pattern/replacement} |
替换所有匹配的 pattern |
| 删除(头部,最短匹配) |
${VAR#pattern} |
从字符串开头删除最短匹配的 pattern |
| 删除(头部,最长匹配) |
${VAR##pattern} |
从字符串开头删除最长匹配的 pattern |
| 删除(尾部,最短匹配) |
${VAR%pattern} |
从字符串末尾删除最短匹配的 pattern |
| 删除(尾部,最长匹配) |
${VAR%%pattern} |
从字符串末尾删除最长匹配的 pattern |
条件判断
测试原语:
[ condition ]:POSIX 标准测试,注意括号两侧必须有空格。
[[ condition ]]:Bash 增强测试,推荐使用。支持正则匹配 =~,支持逻辑运算符 && 和 ||,且对空格和引号的容错率更高。
文件判断
| 参数 |
说明 |
-f |
存在且为普通文件 |
-d |
存在且为目录 |
-e |
存在(文件或目录) |
-r |
存在且可读 |
-x |
存在且可执行 |
字符串判断
| 参数 |
说明 |
-z |
字符串长度为 0 |
-n |
字符串长度不为 0 |
== 或 = |
字符串相等 |
!= |
字符串不等 |
数值判断
| 参数 |
说明 |
-eq |
等于 (equal) |
-ne |
不等于 (not equal) |
-gt |
大于 (greater than) |
-lt |
小于 (less than) |
-ge |
大于或等于 (greater or equal) |
-le |
小于或等于 (less or equal) |
分支语句
- if 分支:
if [[ condition ]]; then
commands
elif [[ condition ]]; then
commands
else
commands
fi
- case 分支(常用于菜单/参数解析,支持通配符):
case "$VAR" in
pattern1)
commands
;;
pattern2|pattern3)
commands
;;
*)
commands # 默认分支
;;
esac
循环
- for 循环:
- 遍历列表:
for item in list; do commands; done
- C语言风格(常用于计数):
for (( i=0; i<10; i++ )); do commands; done
- while 循环 条件为真时执行:
while [[ condition ]]; do
commands
done
- until 循环 条件为假时执行:
until [[ condition ]]; do
commands
done
- 循环控制:
数组
Bash 只支持一维数组,索引从 0 开始。
- 定义:
- 索引数组:
ARR=(val1 val2 val3)
- 关联数组(字典,需提前声明):
declare -A MAP; MAP=([key1]=val1 [key2]=val2)
- 取值:
- 单个元素:
${ARR[index]}
- 所有元素:
${ARR[@]}(常用) 或 ${ARR[*]}
- 获取信息:
- 数组长度:
${#ARR[@]}
- 所有索引(键):
${!ARR[@]}
函数
- 定义:
function func_name() {
commands
}
# 或
func_name() {
commands
}
- 参数与返回值:
- 函数内部通过
$1, $2, $@ 接收参数,与脚本接收参数机制完全一致。
- 函数没有返回字符串的机制。
return 只能返回 0-255 的整数(表示执行状态)。
- 返回字符串的标准做法:函数内部
echo 输出,外部用命令替换捕获 result=$(func_name)。
- 变量作用域:
- 默认函数内的变量是全局的(会污染外部)。
- 必须使用
local VAR=value 声明函数内的局部变量。
逻辑组合与子进程
- 逻辑组合:
cmd1 && cmd2:cmd1 成功(退出码为0)才执行 cmd2。
cmd1 || cmd2:cmd1 失败(退出码非0)才执行 cmd2。
- 子进程执行:
( commands ):括号内的命令在一个全新的子 Shell 中执行,内部的变量修改、目录切换(cd)完全不影响当前父 Shell。
- 进程替换(进阶,但很有用):
<(cmd):将 cmd 的输出视为一个临时文件描述符,传给另一个命令。