Bash 脚本是 Linux/Unix 系统中自动化任务的核心工具,语法简洁且实用,以下是最基础、最常用的语法总结,覆盖脚本结构、变量、流程控制、输入输出等核心场景,适合快速上手。
一、脚本基础结构
1. 脚本开头(指定解释器)
必须放在脚本第一行,指定脚本由 Bash 解释执行:
1
2
3
4
5
6
| #!/bin/bash
# 注释:单行注释以 # 开头(#! 除外)
: '
多行注释:用 : ' 开头,' 结尾(注意引号成对)
可跨多行,适合大段说明
'
|
2. 脚本执行方式
- 先给脚本添加执行权限(仅需一次):
1
| chmod +x script.sh # script.sh 是你的脚本文件名
|
- 执行脚本:
1
2
3
| ./script.sh # 相对路径(推荐,执行当前目录下的脚本)
/home/user/script.sh # 绝对路径
bash script.sh # 直接用 bash 解释器执行(无需执行权限)
|
二、变量与参数
1. 变量定义与使用
- 定义:
变量名=值(等号前后无空格,值含空格需用引号包裹); - 使用:
$变量名 或 ${变量名}({} 用于区分变量边界,避免歧义); - 示例:
1
2
3
4
| name="Bash" # 字符串变量(含空格需用引号:name="Hello Bash")
age=20 # 数值变量(无需引号)
echo "名称:$name" # 输出:名称:Bash
echo "年龄:${age}岁" # 输出:年龄:20岁({} 明确变量范围)
|
2. 环境变量与内置变量
- 环境变量:系统预定义,全大写(如
PATH、HOME、USER),可直接使用:1
2
| echo "用户主目录:$HOME" # 输出当前用户主目录(如 /home/ubuntu)
echo "系统路径:$PATH" # 输出可执行程序的搜索路径
|
- 脚本参数变量(接收命令行输入):
| 变量 | 含义 |
|---|
$0 | 脚本文件名(如 script.sh) |
$1~$n | 第 1~n 个命令行参数 |
$# | 命令行参数总个数 |
$* | 所有参数(合并为单个字符串) |
$@ | 所有参数(保留独立字符串) |
$? | 上一条命令的执行结果(0=成功,非0=失败) |
3. 变量赋值进阶
- 从命令输出赋值(命令替换):
变量名=$(命令) 或 变量名=命令``:1
2
3
| current_dir=$(pwd) # 获取当前目录,赋值给 current_dir
file_count=$(ls | wc -l) # 获取当前目录文件数
echo "当前目录:$current_dir,文件数:$file_count"
|
- 只读变量(不可修改):
readonly 变量名:1
2
3
| pi=3.14159
readonly pi
# pi=3.14 # 报错:无法修改只读变量
|
三、输入与输出
1. 输出(echo/printf)
echo:简单输出(默认换行):1
2
| echo "Hello World" # 输出字符串(可省略引号)
echo -n "请输入姓名:" # -n 不换行(用于接收输入前的提示)
|
printf:格式化输出(类似 C 语言,更灵活):1
2
| printf "姓名:%s,年龄:%d\n" "Alice" 25 # %s 字符串,%d 整数,\n 换行
# 输出:姓名:Alice,年龄:25
|
2. 输入(read)
接收用户键盘输入,存入变量:
1
2
3
| read -p "请输入姓名:" name # -p 直接显示提示信息
read -p "请输入年龄:" age
echo "你输入的姓名:$name,年龄:$age"
|
- 选项:
-t 5 超时时间(5秒未输入则退出),-s 隐藏输入(如输入密码):1
2
| read -s -p "请输入密码:" pwd
echo -e "\n密码已接收" # -e 解析转义字符(\n 换行)
|
四、流程控制(条件判断+循环)
1. 条件判断(if-else)
语法结构
1
2
3
4
5
6
7
| if [ 条件表达式 ]; then # 注意 [ 后、] 前必须有空格
执行命令1 # 条件为真时执行
elif [ 条件表达式2 ]; then
执行命令2 # 条件1为假,条件2为真时执行
else
执行命令3 # 所有条件为假时执行
fi # 结束 if 语句(必须闭合)
|
常用条件表达式
| 表达式 | 含义 |
|---|
$a == $b | 字符串 a 等于 b |
$a != $b | 字符串 a 不等于 b |
-z $a | 字符串 a 为空 |
-n $a | 字符串 a 非空 |
| 表达式 | 含义 |
|---|
$a -eq $b | 数值 a 等于 b |
$a -ne $b | 数值 a 不等于 b |
$a -gt $b | 数值 a 大于 b |
$a -lt $b | 数值 a 小于 b |
$a -ge $b | 数值 a 大于等于 b |
$a -le $b | 数值 a 小于等于 b |
| 表达式 | 含义 |
|---|
-f $file | 文件存在且是普通文件 |
-d $dir | 目录存在 |
-x $script | 文件可执行 |
-e $path | 路径(文件/目录)存在 |
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # 数值比较:判断年龄是否成年
age=18
if [ $age -ge 18 ]; then
echo "已成年"
else
echo "未成年"
fi
# 文件判断:判断文件是否存在
file="test.txt"
if [ -f $file ]; then
echo "$file 存在"
else
echo "$file 不存在,创建文件"
touch $file # 创建文件
fi
|
2. 循环(for/while)
(1)for 循环(遍历列表/范围)
- 遍历列表:
1
2
3
4
5
6
7
8
9
| # 遍历字符串列表
for name in Alice Bob Charlie; do
echo "Hello $name"
done
# 遍历文件列表
for file in $(ls *.txt); do # 遍历当前目录下所有 .txt 文件
echo "文件:$file"
done
|
- 遍历数字范围:
1
2
3
4
5
6
7
8
| # 语法:for 变量 in {起始..结束..步长}(步长可选,默认1)
for i in {1..5}; do
echo "循环次数:$i"
done
for i in {1..10..2}; do # 步长2(1,3,5,7,9)
echo "奇数:$i"
done
|
(2)while 循环(条件为真时执行)
1
2
3
4
5
6
7
8
9
10
11
12
| # 计数器循环(1到5)
i=1
while [ $i -le 5 ]; do
echo "当前值:$i"
i=$((i+1)) # 数值计算($((表达式)) 是算术扩展)
done
# 无限循环(需手动退出)
while true; do
echo "无限循环中(按 Ctrl+C 退出)"
sleep 1 # 暂停1秒
done
|
3. 循环控制(break/continue)
break:退出当前循环;continue:跳过当前循环剩余部分,进入下一次循环;- 示例:
1
2
3
4
5
6
7
8
9
10
| for i in {1..5}; do
if [ $i -eq 3 ]; then
continue # 跳过 i=3 的循环
fi
if [ $i -eq 5 ]; then
break # 当 i=5 时退出循环
fi
echo "当前值:$i"
done
# 输出:1 2 4
|
五、函数
1. 函数定义与调用
1
2
3
4
5
6
7
8
| # 定义函数(两种写法,效果一致)
function hello() { # function 关键字可省略
echo "Hello $1" # $1 是函数的第一个参数(函数内参数用法和脚本一致)
}
# 调用函数
hello "Bash" # 传递参数,输出:Hello Bash
hello "World" # 输出:Hello World
|
2. 函数返回值
Bash 函数无“返回值”概念,可通过以下方式返回结果:
- 直接输出(脚本中用
$(函数名) 捕获); - 用
return 返回状态码(0=成功,非0=失败,仅能返回整数); - 示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| # 函数返回两数之和(通过输出捕获)
add() {
sum=$(( $1 + $2 ))
echo $sum # 输出结果
}
# 调用函数并捕获结果
result=$(add 3 5)
echo "3+5=$result" # 输出:3+5=8
# 用 return 返回状态码
check_num() {
if [ $1 -gt 10 ]; then
return 0 # 成功(状态码0)
else
return 1 # 失败(状态码1)
fi
}
check_num 15
echo $? # 输出 0(成功)
|
六、文件操作
1. 基础文件命令(脚本中常用)
| 命令 | 功能 | 示例 |
|---|
touch 文件名 | 创建空文件 | touch test.txt |
mkdir 目录名 | 创建目录(-p 递归创建) | mkdir -p ./data/logs |
cp 源 目标 | 复制文件/目录(-r 递归) | cp test.txt ./data/ |
mv 源 目标 | 移动/重命名文件 | mv test.txt test_new.txt |
rm 文件名 | 删除文件(-f 强制,-r 递归删目录) | rm -rf ./tmp/(谨慎使用!) |
cat 文件名 | 读取文件内容 | cat test.txt |
grep 关键词 文件名 | 搜索文件内容 | grep "error" log.txt |
2. 文件内容重定向
>:覆盖写入文件(原有内容清空);>>:追加写入文件(原有内容保留);<:从文件读取输入;- 示例:
1
2
3
4
5
6
| echo "Hello" > test.txt # 覆盖写入 test.txt
echo "World" >> test.txt # 追加写入 test.txt
cat test.txt # 输出:Hello\nWorld
# 把命令输出写入文件
ls -l > file_list.txt # 把目录列表写入 file_list.txt
|
七、常用技巧与避坑指南
- 空格问题:
- 变量定义:
name="Bash"(等号前后无空格); - 条件判断:
[ $a -eq $b ]([ 后、] 前必须有空格);
- 字符串含空格:变量赋值和使用时用引号包裹(
name="Hello Bash",echo "$name"); - 数值计算:用
$((表达式)) 或 $[表达式],避免直接用 + 拼接(如 $((a+b)) 而非 $a+$b); - 脚本调试:执行时加
-x 参数,打印每一步执行的命令:bash -x script.sh; - 权限问题:脚本执行前需加执行权限(
chmod +x script.sh),或直接用 bash script.sh 执行; - 路径问题:脚本中尽量用绝对路径(如
/home/user/data),避免相对路径导致的错误。
总结
Bash 脚本核心是“自动化命令组合”,基础语法围绕「变量-流程控制-文件操作」展开:
- 简单任务用「变量+基础命令+重定向」;
- 复杂逻辑用「条件判断+循环+函数」;
- 接收输入用「位置参数/read」,输出结果用「echo/printf/文件重定向」。
多写多练(如自动化部署、日志分析、数据处理脚本)是掌握的关键,遇到问题可通过 bash -x 调试,或查看命令返回状态码($?)定位问题。
💬 评论