Shell 脚本入门课堂讲解

模块一:认识 Shell 与 Shell 脚本

1、什么是 Shell

Shell 是命令解释器,处在用户和系统内核中间层。

  • 用户输入命令 → Shell 翻译给操作系统内核 → 内核调用硬件干活 → 结果通过 Shell 返回屏幕

  • 交互:我们敲命令的黑窗口;非交互:执行脚本文件

查看系统支持哪些 shell:cat /etc/shells ⭐Linux 默认解释器:/bin/bash;sh是 bash 的软链接。

2、什么是 Shell 脚本

把一堆 Linux 命令写到文本文件,给执行权限,批量自动执行。 ✅使用场景:自动化运维、重复批量操作、监控、定时任务 crontab。

脚本第一行:#!/bin/bash 【⭐必考】

叫幻数行(shebang),告诉系统:这个脚本要用 bash 解释器来解析执行。

如果不写,就使用你当前登录的 shell 去执行脚本。 # 除第一行 #! 之外,其余#代表注释,脚本执行会直接忽略。 脚本后缀习惯.sh,后缀只是给人看的,系统不依靠后缀识别脚本。

3、Shell 脚本的 3 种执行方式【⭐高频考点,区分子 shell!】

表格

执行方式 命令 是否需要执行权限 x 运行环境
1、解释器直接运行 bash test.sh / sh test.sh 不需要 开启子 shell运行脚本
2、路径执行 ./test.sh 或绝对路径/root/test.sh ✅必须 chmod +x 加 x 权限 开启子 shell运行脚本
3、source /. 点执行 source test.sh 或者 . test.sh 不需要 当前 shell,不创建子 shell

✨核心区别:source/.不会开子 shell,脚本里定义的变量执行完之后,当前终端还能继续用;另外两种方式开子 shell,脚本结束变量就销毁。 运维建议:调试脚本优先用 bash test.sh,不用操心权限。

4、写脚本完整 4 步

  1. vim 编写脚本

  2. 语法检查调试(sh -n 脚本名检查语法;sh -x 脚本名跟踪执行)

  3. 可选:chmod +x xxx.sh加执行权限

  4. 运行脚本

5、管道 | 和重定向 【⭐工作天天用】

管道 |

cmd1 | cmd2,左边命令输出,作为右边命令的输入,可以多级管道。 示例:

复制代码
#过滤sshd配置,去掉注释行、空行
grep -v "^#" /etc/sshd_config | grep -v "^$"
重定向:3 个标准文件

表格

类型 文件描述符编号 默认设备
标准输入 STDIN 0 键盘
标准输出 STDOUT 1 显示器屏幕
标准错误 STDERR 2 显示器屏幕
  1. 输出重定向
  • > 覆盖写入文件;>> 追加写入文件,不覆盖原有内容
复制代码
uname -p > kernel.txt    #覆盖保存输出
uname -r >> kernel.txt   #追加内容
  1. 错误重定向 2>覆盖错误;2>>追加错误
复制代码
tar xxx 2> error.log
  1. 标准输出 + 错误输出一起保存 &> logfile 等价写法 exec >log.txt 2>&1

/dev/null 黑洞设备,扔进去的内容全部丢弃,脚本经常用来屏蔽报错输出。

  1. 输入重定向 <:把文件代替键盘作为输入,比如 passwd --stdin

这里有个脚本调试小知识点:sh -x 脚本跟踪脚本,每一步变量替换后的命令都会打印,排错神器。


模块二:Shell 变量【重中之重,面试必问】

变量 = 内存的容器,存字符串 / 数字,$变量名读取变量

变量命名规则

  1. 字母、数字、下划线,不能数字开头;区分大小写;习惯大写

  2. =赋值,等号两边绝对不能有空格!!!写错直接报错

  3. 如果值带空格,必须加引号;

  4. 读取变量 $VAR,歧义场景 ${VAR}大括号把变量包起来。

复制代码
name=Tom
echo ${name}Li   #正确输出TomLi;如果写$nameLi,shell会识别变量nameLi,空值

单引号 vs 双引号【⭐超级重点】

  • 单引号 ' ':所见即所得。所有特殊符号全部失效,原样输出,不会解析变量

  • 双引号 " ":会解析里面的变量、特殊符号;空格保留

复制代码
VAR1=123
VAR2='ni hao $VAR1'   #输出 ni hao $VAR1,$不解析
VAR3="ni hao $VAR1"   #输出 ni hao 123,变量解析

变量 4 大类

  1. 用户自定义变量:当前 shell 生效,子 shell 看不见。

  2. 环境变量(全局变量):当前 shell + 所有子 shell 都能读取

    • 查看全局变量:env / printenv

    • 局部转全局:export 变量名

    • 重启消失

    复制代码
    VAR3="hello"
    export VAR3
    • 永久生效:写到配置文件

      • /etc/profile:所有用户全局生效

      • ~/.bash_profile:当前登录用户生效

      • 修改配置后不会立刻生效,执行 source 文件名 刷新配置,不用重新登录

    • 删除变量:unset 变量名

    • 常见系统环境变量:PATH、USER、HOME、PWD、LANG

    • PATH=$PATH:/root 写脚本位置

    PATH:命令搜索路径!系统执行命令时,就在 PATH 的目录列表找程序。把脚本目录加入 PATH 就可以直接敲脚本名字运行。

  3. 位置参数变量(执行脚本时从命令行传参) $0 $1 $2 ... ${10}

  • $0:脚本本身的名字(含路径)

  • $1:第 1 个参数;$2第 2 个参数;大于 9 必须写 ${10},不能写$10

示例脚本 test2.sh

复制代码
#!/bin/bash
echo "脚本名字:$0"
echo "第一个参数:$1"
echo "第二个参数:$2"

运行:sh test2.sh aa bb

  1. 预定义特殊变量【⭐考试必考】

    表格

    变量 作用
    $# 传入脚本的参数总个数

|$*| 全部参数,双引号下合并成1 个字符串 "$1 $2 $3"| |$@| 全部参数,双引号下分开 "$1" "$2" "$3"| |$$| 脚本当前进程 PID 号 | |$?| 上一条命令退出返回值;0 = 命令执行成功;非 0 = 出错 | |$!| 最后一个后台运行进程 PID|

✨"$*" 和 "$@" 的区别,只有套上双引号才体现!for 循环遍历的时候差距巨大。

复制代码
for i in "$*" ;do echo $i ;done #循环只跑1次,把所有参数当一个整体
for i in "$@" ;do echo $i ;done #循环多次,每一个参数单独循环

模块三:Shell 数学运算

bash 原生只支持整数;小数浮点要借助 bc 工具

1、expr 命令(只整数运算)

运算符两边必须空格 ,乘法*要转义 \*,不然会被当做通配符。

复制代码
expr 2 + 5
expr 10 \* 2
expr 10 / 3
expr 12 % 5
#赋值给变量
x=3
y=4
res=$(expr $x + $y)

2、bc 工具【⭐小数、浮点数计算】

交互式直接敲bc进入计算器;脚本中用管道传给 bc scale=N 设置保留 N 位小数

复制代码
#脚本中计算 7 *2.5,保留4位小数
A=$(echo "scale=4;7 * 2.5" | bc)
echo $A

⚠️坑点:不要给数字加单引号传给 bc!bc 不识别引号字符,报 illegal character 错误。


模块四:条件测试 test / 【if 判断的基础】

两种写法完全等价:

复制代码
test 条件
[  条件  ]

⚠️【致命坑】中括号[ ],括号内侧两边必须留有空格!少空格直接语法报错

三大测试类别:整数测试、字符串测试、文件测试

1、整数比较(只能比较整数)

表格

符号 含义
-eq 等于 equal
-ne 不等于 not equal
-gt 大于 greater than
-ge 大于等于 greater equal
-lt 小于 less than
-le 小于等于 less equal

示例:

复制代码
[ "$a" -gt "$b" ] && echo yes || echo no

2、文件测试【⭐考试高频】

表格

选项 功能
-e 文件名 文件或目录是否存在
-f 是否普通文件
-d 是否目录
-r/-w/-x 可读、可写、可执行权限
-s 文件存在并且文件大小不为空
! 取反,感叹号前后空格 [ ! -f test.txt ]

文件新旧、inode 判断【你刚才提问的知识点】

复制代码
[ file1 -nt file2 ] #newer than:file1修改时间比file2新,**对比mtime修改时间,不是inode**
[ file1 -ot file2 ] #older than:file1修改时间比file2旧
[ file1 -ef file2 ] #判断两个文件是否同一个文件:比对设备号+inode号(硬链接识别)

3、read 交互命令

实现脚本和用户键盘交互输入 read [选项] 变量名

  • -p "提示文字":打印提示

  • -t 秒数:超时时间,超时自动结束不等待输入

复制代码
read -p "请输入名字:" NAME
read -t 10 -p "请输入年龄:" AGE

📚 全章节重点知识汇总

一、核心必背清单

  1. shebang #!/bin/bash 脚本第一行,指定解释器;#注释

  2. 脚本 3 种运行方式,重点区分 source 不生成子 shell,bash/./ 会生成子 shell

  3. 3 重定向编号:0 标准输入,1 标准输出,2 标准错误;>覆盖 >>追加;&>混合输出;/dev/null黑洞

  4. 变量:

    • =赋值无空格;大括号${VAR}消除歧义;

    • 单引号原样输出,双引号解析变量;

    • export 把局部变量升级环境变量;永久写到/etc/profile / ~/.bash_profile,source 生效;

  5. 特殊预定义变量:$0 $1 $# $* $@ $? $$,重点区分"$*"与"$@"

  6. 数学运算:expr 仅整数;bc 做浮点,scale 控制小数位

  7. 条件测试

    复制代码
    [ 条件 ]

    括号内侧必须空格

    • -gt/-lt/-eq整数比较

    • -f/-d/-e文件存在性;-nt/-ot比较文件修改时间;-ef比对 inode

  8. 脚本调试:sh -x 脚本名跟踪执行流程

相关推荐
Profile排查笔记1 小时前
有哪些开源指纹浏览器项目?先核对客户端、内核与许可证
前端·人工智能·后端·自动化
CodeGL1 小时前
16、Python Web开发
开发语言·前端·python
FRing031 小时前
JavaScript入门到精通二十九(内置构造函数(Object、Array))
开发语言·前端·javascript
AAA程序技术1 小时前
从 DOM 到屏幕:浏览器渲染管线六步拆解
前端·浏览器
zach1 小时前
useContext 深入讲解:组件透传、原理与最佳实践
前端
张一凡932 小时前
AI 改完代码,人却不知道它改了什么:架构漂移才是真正的成本
前端·后端·agent
sycmancia2 小时前
Qml——Text元素
java·前端·html
DevChronosands_2 小时前
浅谈感受之 React 与 Vue 😒
前端
代码猎人2 小时前
前端怎么掌握模块化
前端