Shell 脚本从 0 到精通|脚本规范 + 变量 + 数值运算 + 条件测试(可直接复制,面试必备)
✨简介:本文整合 Shell 入门全套核心知识点,从第一个 Shell 脚本编写、脚本执行方式、开发规范,到 Shell 基础 / 进阶变量、数值运算、4 大条件测试语法test/\[\]/\[]/(()),包含大量生产案例、对比表格、踩坑点,适合 Linux 运维、后端开发、面试刷题,全部代码可直接复制运行。
📖适用人群:Linux 新手、运维工程师、校招面试、自动化脚本学习
📚核心内容:第一个 Shell 脚本、4 种脚本执行方式、Shell 开发规范、变量基础 & 进阶、Shell 数值计算、条件测试全解(文件 / 字符串 / 整数 / 逻辑运算)
1 编写第一个 Shell 脚本
1.1 脚本解释器(幻数#!)
脚本第一行必须指定解释器,#!叫做幻数,内核根据该行调用对应解释器执行脚本。
bash
#!/bin/bash # 推荐,bash解释器
#!/bin/sh
注意:必须写在脚本第一行,否则变成普通注释。
/bin/sh是bash的软链接,生产环境优先使用 #!/bin/bash。
1.2 Shell 注释
#后面全部为注释,不会被解释器执行。
单行注释:# 这是注释
建议尽量英文注释,避免中文乱码。
1.3 HelloWorld 示例
bash
#!/bin/bash
# Date:2026‑08‑23
# Author:demo
echo "Hello World !"
1.4 简单实战脚本示例
info.sh 获取系统基础信息
bash
#!/bin/bash
echo "====系统信息===="
echo "主机名: $(hostname)"
echo "当前时间: $(date)"
echo "内核版本: $(uname -r)"
echo "登录用户: $(whoami)"
backup_log.sh 日志备份脚本
bash
#!/bin/bash
time=$(date +%Y%m%d_%H%M%S)
cp /var/log/messages /tmp/messages_${time}.bak
echo "备份完成:/tmp/messages_${time}.bak"
2 Shell 脚本 4 种执行方式
| 执行方式 | 是否需要 x 权限 | 是否开启子 shell | 说明 |
|---|---|---|---|
| bash test.sh / sh test.sh | 不需要 | ✅是 | 直接调用解释器执行脚本 |
| ./test.sh 绝对 / 相对路径 | ✅需要 | ✅是 | 必须chmod +x test.sh赋予执行权限 |
| source test.sh / . test.sh | 不需要 | ❌否 | 当前 shell 执行,变量、函数会保留在当前终端 |
| bash < test.sh / cat test.sh | bash | 不需要 | ✅是 | 较少使用,适合批量命令流水线 |
💡重点:source的核心用途:加载配置文件、脚本之间传递变量与函数;其余 3 种方式会启动子 shell,脚本内部变量执行结束就消失。
示例对比 source 与 sh 执行区别:
bash
# test2.sh
user=$(whoami)
bash
sh test2.sh
echo $user # 输出为空,子shell变量不回传
. test2.sh
echo $user # 输出root,当前shell执行,变量保留
3 Shell 脚本开发规范与最佳习惯
-
首行必须写
#!/bin/bash -
脚本头部增加版本、作者、日期、功能描述注释
bash
#!/bin/bash
# Date:2026‑08‑23
# Author:demo@shturl.
# Desc: 系统日志备份脚本
# Version:1.0
-
脚本后缀建议
.sh;存放路径统一管理 -
尽量避免中文注释,防止乱码
-
成对符号
{} [] '' ""一次性写完,再填入内容,防止漏写 -
[]、[[]]内部两端必须留空格 -
if、for、while、case 先把完整框架写好,再填充代码
-
使用缩进,提升可读性;变量字符串建议加双引号;等号两边不能有空格
bash
file="test.txt" #正确
file = "test.txt" #错误!变量赋值等号不能带空格
4 Shell 变量基础与进阶
4.1 变量定义规则
-
变量名由字母、数字、下划线组成,不能数字开头
-
赋值等号左右不能空格
-
双引号
"":解析变量;单引号'':原样输出,不解析变量;反引号```执行命令。
bash
name="zhangsan"
echo "$name"
echo '$name'
cmd=`date`
4.2 环境变量、局部变量、特殊位置变量
普通变量:脚本内生效;
环境变量export:子 shell 也能读取;
特殊变量:
| 变量 | 含义 |
|---|---|
| $0 | 脚本本身名字 |
| 1 2 ... $n | 脚本传入第 1、2... 参数 |
| $# | 传入参数总个数 |
| @/@/@/* | 获取全部参数 |
| $? | 上一条命令退出返回值,0 代表成功,非 0 失败 |
$?是运维高频使用:用来判断上一条命令执行是否成功。
5 Shell 变量数值计算实践
Shell 本身不支持直接数学运算,4 种常用计算方式:
$((算术表达式)) 【最推荐】整数运算
bash
a=10
b=20
echo $((a+b))
echo $((a*b))
echo $((a++))
$表达式 整数运算
bash
echo $[10+20]
expr命令,注意运算符前后空格
bash
expr 10 + 20
bc工具:支持小数浮点运算
bash
echo "3.14*2" | bc
注意 :$(( ))只支持整数,小数计算必须用 bc。
6 Shell 条件测试全解(test / \[\] / \[] / (()))
条件测试返回退出码:0 代表真,非 0 代表假 ,配合if或者&& ||使用。
4 种语法:
-
test 表达式 -
[ 表达式 ]👉 test 等价,两端必须空格,工作最常用 -
[[ 表达式 ]]👉扩展 test,支持&& || =~正则匹配,两端空格 -
((算术表达式))👉专门整数运算判断,不需要两端空格
简单示例:
bash
# test
test -f /etc/passwd && echo "文件存在" || echo "不存在"
# []
[ -f /etc/passwd ] && echo true || echo false
# [[]]
[[ -f /etc/passwd ]] && echo true || echo false
# (())
(( 10>5 )) && echo "10大于5"
小技巧:&&前面条件成立才执行后面;||前面条件失败才执行后面。
多条命令简写(替代 if):
bash
[ -w ~/.bashrc ] && {
echo "alias sa='ssh root@a'" >> ~/.bashrc
echo "alias sb='ssh root@b'" >> ~/.bashrc
}
7 条件测试:文件判断表达式
| 参数 | 含义 |
|---|---|
| -d FILE | 文件存在且为目录 |
| -f FILE | 文件存在且普通文件 |
| -e FILE | 文件存在(不区分文件 / 目录) |
| -r FILE | 文件存在且可读 |
| -w FILE | 文件存在且可写 |
| -x FILE | 文件存在且可执行 |
| -L FILE | 文件存在且是软链接 |
| -s FILE | 文件存在且大小不为 0 |
| FILE1 -nt FILE2 | file1 比 file2 新(修改时间) |
| FILE1 -ot FILE2 | file1 比 file2 旧 |
示例:
bash
data_path=/tmp/testdir
mkdir -p ${data_path}
[ -d ${data_path} ] && echo "${data_path} 目录存在"
rmdir ${data_path}
[ -d ${data_path} ] || echo "${data_path} 目录不存在"
8 条件测试:字符串判断
| 操作符 | 说明 |
|---|---|
| -z "STRING" | 字符串长度为 0(空字符串)为真 |
| -n "STRING" | 字符串非空为真 |
| "s1" = "s2" | 字符串相等 |
| "s1" != "s2" | 字符串不相等 |
⚠️坑点:字符串变量一定要加双引号,防止变量为空出现语法报错;比较符号两边必须空格。
\[]专属 =~ 正则匹配
bash
str=12345
[[ "$str" =~ ^[0-9]+$ ]] && echo "是数字" || echo "不是数字"
⚠️注意:=~右边正则模式不要加引号,加引号会变成普通字符串匹配,不再解析正则。
9 条件测试:整数二元比较
⚠️[]中不能直接使用> < >= <=,需要转义\> \<;推荐分开使用。
| \[\] / test符号 | (()) / \[]符号 | 含义 |
|---|---|---|
| -eq | == | 等于 |
| -ne | != | 不等于 |
| -gt | > | 大于 |
| -ge | >= | 大于等于 |
| -lt | < | 小于 |
| -le | <= | 小于等于 |
示例:
bash
a=98
b=99
[ $a -lt $b ] && echo "a小于b"
(( a < b )) && echo "a小于b"
10 条件测试:逻辑操作符
| \[\] / test内部 | \[] / (())内部 | 含义 |
|---|---|---|
| -a | & | 逻辑与,两边同时成立才真 |
| -o | || | 逻辑或,任意一个成立即为真 |
| ! | ! | 逻辑非,取反 |
示例:
bash
file="/etc/passwd"
# [] 写法 -a
[ -f "${file}" -a -r "${file}" ] && head -1 "${file}"
# [[]] 写法 &&
[[ -f "${file}" && -r "${file}" ]] && head -1 "${file}"
注意 :&& ||写在表达式外部,用来连接多个[]/[[]]语句。
11 test / \[\] / \[] / (()) 完整对比总结
| 判断表达式 | \[\] | test | \[] | (()) |
|---|---|---|---|---|
| 边界需要空格 | ✅需要 | ✅需要 | ✅需要 | ❌不需要 |
| 内部逻辑符号 | ! -a -o | ! -a -o | ! && || | ! && || |
| 整数比较 | ‑eq ‑ne ‑gt ‑ge ‑lt ‑le | ‑eq ‑ne ‑gt ‑ge ‑lt ‑le | 支持‑eq 系列 | == != > >= < <= |
| 字符串比较 | = != | = != | = != | 仅数字 |
| 通配符 / 正则 | ❌不支持 | ❌不支持 | ✅支持=~ | ❌不支持 |
生产建议:
-
文件、字符串判断优先使用
[] -
需要正则、
&& ||内部逻辑,用[[]] -
纯整数判断运算直接用
(( ))
12 新手高频坑点汇总
-
[ ]、[[ ]]忘记前后空格,直接报语法错误; -
字符串变量不加双引号,变量为空时脚本异常;
-
[]内部直接写> <不转义,不会报错但是逻辑结果错误; -
=~正则右边模式加引号,正则失效; -
变量赋值等号左右加空格;
-
source与bash ./xxx.sh混淆,子 shell 中变量无法回传; -
$?只能捕获上一条命令结果,中间不能插入其他命令。
💡 点赞 + 收藏!Shell 入门完整手册,面试刷题直接看,后续更新 if/case/ 循环实战!