参数和变量

参数 含义
$0 当前脚本的名字(或调用脚本时使用的命令)
$1 第1个参数
$2 第2、3、4…参数,以此类推
$# 脚本传递参数的个数
$@ 脚本传递的全部参数,以列表形式展开
$* 脚本传递的全部参数,作为单个字符串展开
$? 最近一条命令的退出状态(0 表示成功,非 0 表示失败)
$$ 当前脚本的进程 ID
$! 最近一条在后台执行的命令的PID
$_ 上一条命令最后一个参数

比较运算符

类型 运算符 意义 示例
数字比较 -eq 等于 [ $a -eq $b ]
-ne 不等于 [ $a -ne $b ]
-gt 大于 [ $a -gt $b ]
-ge 大于等于 [ $a -ge $b ]
-lt 小于 [ $a -lt $b ]
-le 小于等于 [ $a -le $b ]
字符串比较 = 相等 [ "$a" = "$b" ]
!= 不相等 [ "$a" != "$b" ]
-z 空字符串 [ -z "$a" ]
-n 非空字符串 [ -n "$a" ]
文件检测 -e 文件是否存在 [ -e /path/to/file ]
-f 文件是否为普通文件 [ -f /path/to/file ]
-d 文件是否为目录 [ -d /path/to/dir ]
-r 文件是否可读 [ -r /path/to/file ]
-w 文件是否可写 [ -w /path/to/file ]
-x 文件是否可执行 [ -x /path/to/file ]

控制结构

if 判断结构

1
2
3
4
5
6
7
if [ 条件 ]; then
# 满足条件时执行
elif [ 其他条件 ]; then
# 满足其他条件时执行
else
# 否则执行
fi

示例:

1
2
3
4
5
6
7
8
num=5
if [ $num -gt 3 ]; then
echo "$num 大于 3"
elif [ $num -eq 3 ]; then
echo "$num 等于 3"
else
echo "$num 小于 3"
fi

其他(通用):

  1. break:退出当前循环。
  2. continue:跳过当前迭代,进入下次循环。

for 循环结构

1
2
3
for i in 1 2 3; do
echo "数字: $i"
done

示例(列表):

1
2
3
4
fruits=("apple" "banana" "orange")
for fruit in "${fruits[@]}"; do
echo "我喜欢 $fruit"
done

while 循环结构

1
2
3
4
5
count=1
while [ $count -le 5 ]; do
echo "count = $count"
((count++))
done

until 循环

和 while 相反,当条件为 false时持续执行:

1
2
3
4
5
count=1
until [ $count -gt 5 ]; do
echo "count=$count"
((count++))
done

用途:适合循环直到某个条件成立

select 菜单结构

让脚本提供简单的菜单:

1
2
3
4
5
6
7
8
select option in "Apple" "Banana" "Quit"; do
case $option in
Apple) echo "你选择了苹果";;
Banana) echo "你选择了香蕉";;
Quit) break;;
*) echo "无效选择";;
esac
done

用途:适合脚本做简单交互

使用 getopts 做参数解析

让脚本接受参数选项,例如:

1
2
3
4
5
6
7
8
while getopts "a:b:c" opt; do
case $opt in
a) echo "选项 a 值:$OPTARG";;
b) echo "选项 b 值:$OPTARG";;
c) echo "选项 c";;
*) echo "无效选项";;
esac
done

用途:脚本参数更灵活,更标准化

case 结构

1
2
3
4
5
6
7
8
9
read -p "请输入一个颜色: " color
case $color in
red)
echo "你喜欢红色";;
blue)
echo "你喜欢蓝色";;
*)
echo "颜色未知";;
esac

函数定义和调用

1
2
3
4
5
6
my_func() {
echo "这是一个函数"
}

# 调用
my_func

用途:封装代码片段、结构化脚本

脚本退出和错误检测

1
2
3
4
5
6
7
8
exit 0           # 正常退出
exit 1 # 错误退出

# 检查命令是否成功
if ! command_here; then
echo "命令执行失败"
exit 1
fi

重定向和管道

  • 重定向:

    1
    2
    3
    4
    command > file.txt           # 覆盖
    command >> file.txt # 追加
    command 2> error.txt # 错误重定向
    command > all.txt 2>&1 # 标准和错误全部重定向
  • 管道:

    1
    ps aux | grep bash           # 将 ps 的结果传递给 grep

脚本参数处理

  • 检查是否提供参数:

    1
    2
    3
    4
    if [ $# -lt 1 ]; then
    echo "Usage: $0 <param1> [param2...]"
    exit 1
    fi
  • 获取参数:

    1
    2
    3
    for arg in "$@"; do
    echo "参数: $arg"
    done

错误检测和脚本退出控制

检查命令是否存在

1
2
3
4
if ! command -v curl &> /dev/null; then
echo "curl 未安装,请先安装!"
exit 1
fi

检查命令是否成功

每个命令执行完都有一个退出状态

  • 0 表示成功。
  • 0 表示失败。

示例:

1
2
3
4
5
mkdir mydir
if [ $? -ne 0 ]; then
echo "mkdir 执行失败!"
exit 1
fi

检查脚本参数是否完整

在脚本一开始检查参数:

1
2
3
4
if [ $# -lt 1 ]; then
echo "用法: $0 <参数1> [参数2...]"
exit 1
fi

检查命令是否存在

检查某命令是否已安装:

1
2
3
4
if ! command -v curl &> /dev/null; then
echo "curl 没安装,请先安装!"
exit 1
fi

严格错误检查

用脚本开头加:

1
set -euo pipefail
  • -e:检测错误,脚本出错立刻退出。
  • -u:检测使用未定义变量。
  • -o pipefail:检测管道中任一命令失败时让脚本退出。

完成后释放资源

trap 在脚本退出时做收尾:

1
2
3
4
5
temp_file=$(mktemp)

trap 'rm -f $temp_file' EXIT

echo "用完后,脚本退出时会自动删除 $temp_file"