shell脚本
Shell 脚本(以 Bash 为例)是 Linux 运维、自动化部署、CI/CD、数据处理等场景中最常用的脚本语言之一。真正高频使用的语法并不多,大约 20% 的语法覆盖 80% 的工作场景。
下面按实际开发频率进行讲解。
一、Shell脚本基本结构(★★★★★)
几乎所有 Shell 脚本都遵循以下结构:
#!/bin/bash
# 注释
变量定义
函数定义(可选)
主逻辑
例如:
#!/bin/bash
name="Tom"
echo "Hello $name"
运行:
chmod +x hello.sh
./hello.sh
输出:
Hello Tom
二、变量(★★★★★)
Shell 中所有变量默认都是字符串。
1)定义变量
name="Alice"
age=20
注意:
name = "Alice"
这是错误写法,= 两边不能有空格。
2)使用变量
echo $name
推荐:
echo "${name}"
原因:
file="abc"
echo "${file}.txt"
输出:
abc.txt
否则:
echo "$file.txt"
Shell 会尝试寻找变量 file.txt。
3)只读变量
readonly PI=3.14
以后不能修改。
4)删除变量
unset name
三、命令替换(★★★★★)
把命令执行结果赋值给变量。
推荐:
today=$(date)
以前写法:
today=`date`
现在几乎不用。
例如:
files=$(ls)
四、用户输入(★★★★★)
读取输入:
read name
例如:
echo "请输入名字:"
read name
echo "你好:$name"
更常见:
read -p "请输入用户名:" username
五、位置参数(★★★★★)
脚本:
./test.sh Tom 18
Shell:
$0
脚本名
$1
第一个参数
$2
第二个参数
例如:
#!/bin/bash
echo "$1"
echo "$2"
运行:
./test.sh Tom 18
输出:
Tom
18
常见特殊变量:
| 变量 | 含义 |
|---|---|
| $0 | 脚本名 |
| $1~$9 | 参数 |
| $# | 参数个数 |
| $* | 所有参数 |
| $@ | 所有参数(推荐) |
| $? | 上一条命令返回值 |
| $$ | 当前进程PID |
例如:
echo $#
统计参数数量。
六、条件判断 if(★★★★★)
最常见:
if [ 条件 ]
then
命令
fi
例如:
age=20
if [ $age -ge 18 ]
then
echo "成年人"
fi
更常见:
if [ $age -ge 18 ]; then
echo "成年人"
fi
if else
if [ $age -ge 18 ]
then
echo "成人"
else
echo "未成年"
fi
多分支:
if [ $score -ge 90 ]
then
echo A
elif [ $score -ge 80 ]
then
echo B
else
echo C
fi
七、判断条件(★★★★★)
数字比较
| 运算符 | 说明 |
|---|---|
| -eq | 等于 |
| -ne | 不等于 |
| -gt | 大于 |
| -lt | 小于 |
| -ge | 大于等于 |
| -le | 小于等于 |
例如:
[ 5 -gt 3 ]
字符串:
[ "$a" = "$b" ]
不等:
[ "$a" != "$b" ]
空字符串:
[ -z "$name" ]
非空:
[ -n "$name" ]
文件判断:
| 判断 | 说明 |
|---|---|
| -f | 普通文件 |
| -d | 目录 |
| -e | 存在 |
| -r | 可读 |
| -w | 可写 |
| -x | 可执行 |
例如:
if [ -f test.txt ]
八、循环(★★★★★)
for
最常见:
for i in 1 2 3
do
echo $i
done
输出:
1
2
3
遍历文件:
for file in *.txt
do
echo "$file"
done
C 风格:
for ((i=0;i<5;i++))
do
echo $i
done
while
例如:
i=1
while [ $i -le 5 ]
do
echo $i
i=$((i+1))
done
无限循环:
while true
do
...
done
九、case(★★★★☆)
替代大量 if。
case $1 in
start)
echo "启动"
;;
stop)
echo "停止"
;;
restart)
echo "重启"
;;
*)
echo "未知命令"
;;
esac
经常用于:
- 服务启动脚本
- 命令解析
- 菜单程序
十、函数(★★★★★)
定义:
hello() {
echo "Hello"
}
调用:
hello
带参数:
add() {
echo $(($1+$2))
}
add 3 5
返回值:
Shell 函数返回的是退出状态码(0~255):
foo() {
return 0
}
真正需要返回数据时,通常使用 echo:
get_name() {
echo "Tom"
}
name=$(get_name)
十一、算术运算(★★★★★)
推荐:
sum=$((3+5))
变量:
a=5
b=3
echo $((a+b))
自增:
((i++))
或者:
((i+=2))
十二、字符串操作(★★★★☆)
长度:
echo ${#name}
截取:
echo ${name:2:3}
替换:
echo ${name/a/A}
删除前缀:
${file#*/}
删除后缀:
${file%.txt}
例如:
file=test.txt
echo ${file%.txt}
输出:
test
十三、数组(★★★★☆)
定义:
arr=(A B C)
访问:
echo ${arr[0]}
遍历:
for i in "${arr[@]}"
do
echo "$i"
done
长度:
echo ${#arr[@]}
十四、文件读取(★★★★★)
最经典:
while read line
do
echo "$line"
done < file.txt
逐行读取文件。
十五、重定向与管道(★★★★★)
覆盖输出:
echo hello > file.txt
追加:
echo hello >> file.txt
错误输出:
command 2> error.log
标准输出和错误一起:
command > all.log 2>&1
管道:
cat file.txt | grep Tom
十六、退出状态(★★★★★)
判断上一条命令:
cp a b
if [ $? -eq 0 ]
then
echo "成功"
fi
更推荐直接写:
if cp a b
then
echo "成功"
else
echo "失败"
fi
十七、高频实战场景
1. 批量处理日志
for file in *.log
do
gzip "$file"
done
2. 检查目录是否存在
if [ ! -d backup ]; then
mkdir backup
fi
3. 判断程序是否执行成功
if tar -czf backup.tar.gz data
then
echo "备份成功"
else
echo "备份失败"
fi
4. 遍历所有参数
for arg in "$@"
do
echo "$arg"
done
5. 读取配置文件
while IFS='=' read -r key value
do
echo "$key -> $value"
done < config.ini
十八、学习优先级(按使用频率)
| 优先级 | 语法 | 典型场景 |
|---|---|---|
| ⭐⭐⭐⭐⭐ | 变量、命令替换、参数 | 获取输入、传递数据 |
| ⭐⭐⭐⭐⭐ | if、测试表达式 ([ ]) |
判断文件、字符串、数字 |
| ⭐⭐⭐⭐⭐ | for、while |
批量处理文件、循环执行任务 |
| ⭐⭐⭐⭐⭐ | 函数 | 代码复用、模块化脚本 |
| ⭐⭐⭐⭐⭐ | 重定向、管道 | 日志处理、命令组合 |
| ⭐⭐⭐⭐☆ | case |
命令分发、菜单程序 |
| ⭐⭐⭐⭐☆ | 数组 | 批量数据处理 |
| ⭐⭐⭐⭐☆ | 字符串操作 | 文件名处理、路径解析 |
| ⭐⭐⭐☆☆ | select、关联数组、coproc |
特定高级场景 |
建议学习顺序:先掌握变量 → 参数 → if → 循环 → 函数 → 重定向/管道,这些内容足以编写和维护绝大多数 Shell 自动化脚本;再进一步学习数组、字符串处理和 case,即可覆盖日常运维和开发中的绝大多数需求。

浙公网安备 33010602011771号