Shell脚本编程

📅 2026/7/19 13:50:08
Shell脚本编程
目录 Shell脚本编程Linux自动化运维入门指南前言一、shell入门1.1shell是什么1.2 shell脚本的概念二、脚本编写与执行2.2 创建脚本四步法2.3 四种执行方式第3章变量——数据的储物柜3.1 定义与引用3.2 echo高级用法第4章特殊变量与引号4.1 双引号 vs 单引号4.2 命令替换把命令结果存进变量4.3 read交互式输入第5章变量运算5.1 四则运算5.2 let直接修改变量5.3 bc浮点数计算第6章变量类型与作用范围6.1 自定义变量 vs 环境变量6.2 只读变量不可修改6.3 位置变量获取脚本参数6.4 预定义变量6.5 export变量出国旅行第7章重定向与管道——数据流的艺术7.1 三条流水线7.2 输出重定向7.3 输入重定向与Here Document7.4 管道把命令串起来第8章综合实战——三个经典脚本实战1服务器健康检查实战2日志备份清理实战3批量创建用户从文件读取总复习速查表 Shell脚本编程Linux自动化运维入门指南前言在Linux的世界里重复性的系统管理工作如备份、监控、批量部署如果每次都手动敲命令不仅效率低下还容易出错。Shell脚本就是为了解决这个问题而生的——它能让电脑自动干活把复杂的任务变成一键执行的脚本。旨在帮助你从零开始理解Shell的核心概念掌握变量、运算、重定向等关键技术最终能够独立编写简单的自动化运维脚本。让我们一起开启Linux自动化之旅吧一、shell入门1.1shell是什么Shell是用户和Linux内核之间的“翻译官”——你把命令交给Shell它翻译成内核能懂的语言执行完再把结果还给你。用户通过键盘输入人类可读的命令如ls,cp。Shell接收命令将其“翻译”成操作系统内核能听懂的机器指令。Linux内核执行这些指令操作硬件或文件系统。反馈回路内核将执行结果返回给 ShellShell 再将其格式化显示给用户。交互流程图解用户输入→Shell (翻译)→Linux内核 (执行)→执行结果→Shell (反馈)→用户看到结果三大功能命令翻译、输入输出管理、编程能力把命令写成脚本自动执行功能模块详细说明实际应用场景示例命令翻译解析用户输入的字符串调用对应的系统程序或内置指令。输入dateShell 找到/bin/date并运行显示时间。输入输出管理控制数据的流向重定向、管道决定数据从哪里来到哪里去。使用将日志写入文件或使用 编程能力支持变量、循环、判断等逻辑能将多条命令组合成脚本自动执行。编写一个.sh文件每天凌晨自动备份数据库并发送邮件通知。常见Shell类型/bin/bash– 默认Shell最常用 ★/bin/sh– bash的简化版软链接到bash/bin/tcsh– C Shell的增强版查看当前Shellcat /etc/shells # 查看系统支持的所有Shellecho $SHELL # 查看当前正在用的Shell1.2 shell脚本的概念Shell脚本就是“命令清单”把一堆要执行的命令按顺序写进文件电脑自动一条条执行这就是脚本。#!/bin/bash# 查看系统信息cd /bootecho 当前目录pwdecho 内核文件ls -lh vm*本章总结Shell是用户和内核之间的桥梁负责翻译命令、管理输入输出、支持编程。常见的有bash默认、sh、tcsh。脚本本质上就是把多条命令按顺序写入文件让计算机自动执行适合系统管理、批量处理和自动化运维。记住Shell是翻译官脚本是命令清单。二、脚本编写与执行2.1shell脚本的基本构成部分说明示例脚本声明告诉系统用哪个解释器#!/bin/bash注释给人看的说明不执行# 这是注释命令实际干活的语句echo Hello2.2 创建脚本四步法创建文件 → 添加权限 → 检查语法 → 执行脚本↓ ↓ ↓ ↓vim xxx.sh chmod x bash -n ./xxx.sh# 1. 创建文件vim first.sh# 内容#!/bin/bashecho 我的第一个脚本# 2. 添加执行权限Linux的安全机制chmod x first.sh# 3. 检查语法不执行只看有没有写错bash -n first.sh # 没输出语法正确# 4. 执行./first.sh2.3 四种执行方式方式命令需权限运行环境变量保留路径执行./script.sh✓子Shell✗bash执行bash script.sh✗子Shell✗source执行source script.sh✗当前Shell✓重定向执行sh script.sh✗子Shell✗关键区别source在当前Shell中运行定义的变量会保留bash和./在子Shell中运行变量执行完就消失。# 测试用source执行后变量还在cat test.sh EOFname测试echo 脚本内 name$nameEOFbash test.shecho $name # 没输出变量没了source test.shecho $name # 输出测试变量还在本章总结一个完整脚本包含三部分——声明shebang、注释、命令。创建脚本走四步创建文件→添加执行权限→检查语法→执行。执行方式分四种路径执行最正式、bash执行不需要权限、source执行变量会保留、重定向执行。正式运行用./测试用bash定义变量/函数用source。第3章变量——数据的储物柜3.1 定义与引用bash复制下载# 格式变量名变量值等号两边不能有空格 name小明 # ✓ 正确 age18 # ✓ 正确 name 小明 # ✗ 错误会被当成命令执行 # 规则 # - 只能包含字母、数字、下划线 # - 不能以数字开头 # - 区分大小写 # 引用加$符号 echo $name # 输出小明 echo 我叫${name}今年${age}岁 # 用{}明确边界推荐什么时候必须用花括号{}bash复制下载fruit苹果 echo $fruit价格 # 输出苹果价格没问题 echo ${fruit}价格 # 更安全推荐 filereport echo ${file}.txt # 输出report.txt不加{}会找变量file.txt3.2 echo高级用法选项作用示例-n不换行echo -n 请输入-e识别转义字符echo -e a\nbbash复制下载# 换行 echo -e 第一行\n第二行 # 制表符对齐 echo -e 姓名\t\t年龄\t\t城市 echo -e 张三\t\t25\t\t北京 # 彩色输出用ANSI转义码 echo -e \033[31m红色文字\033[0m echo -e \033[32m绿色文字\033[0m 本章总结变量是存储数据的容器定义时等号两边绝对不能有空格。引用变量用$符号复杂场景用${变量名}明确边界。echo的两个常用选项-n不换行、-e识别转义字符换行\n、制表\t、颜色\033。记住定义无空格引用加$边界用{}。第4章特殊变量与引号4.1 双引号 vs 单引号引号识别变量示例输出双引号✓ 是echo $name小明单引号✗ 否echo $name$name记忆口诀双引号里变量“活”会替换单引号里全“死”原样输出4.2 命令替换把命令结果存进变量两种写法推荐用$()bash复制下载# 反撇号Tab键上方容易看错 timedate %T # $() 写法推荐更容易阅读和嵌套 time$(date %T) echo 当前时间$time # 获取日期做文件名 filenamebackup_$(date %Y%m%d).tar.gz echo 备份文件名$filename # 嵌套优势明显 result$(rpm -qf $(which useradd)) # 清晰 resultrpm -qf \which useradd\ # 容易乱4.3 read交互式输入bash复制下载# 基本方式 echo 请输入姓名 read name echo 你好$name # 用-p简化推荐 read -p 请输入姓名 name echo 你好$name # 密码输入不显示 read -s -p 请输入密码 pwd echo # 限制字符数如手机号11位 read -n 11 -p 请输入手机号 phone echo # 超时处理5秒不输入自动跳过 read -t 5 -p 5秒内输入 input if [ -z $input ]; then echo 超时了 fi 本章总结双引号内变量会替换单引号内原样输出。命令替换用$(命令)比反撇号更清晰、易嵌套。read命令实现交互式输入常用选项-p显示提示、-n限制字符数、-s隐藏输入密码、-t设置超时。记住需要变量值用双引号命令替换用$()交互输入用read。第5章变量运算5.1 四则运算方式语法特点推荐度exprexpr 2 \* 3需空格、乘号需转义★★☆$[]echo $[2 * 3]简洁乘号不需转义★★★$(())echo $((2 * 3))最常用乘号不需转义★★★letlet num5直接修改变量本身★★★bash复制下载# expr注意空格和转义 expr 5 3 # 8 expr 5 \* 3 # 15*要转义 expr 10 / 3 # 3整数除法 # $[] 和 $(())推荐日常使用 echo $[5 3] # 8 echo $[5 * 3] # 15不用转义 echo $((10 / 3)) # 3 # 变量运算 a10 b20 sum$((a b)) echo $sum # 305.2 let直接修改变量bash复制下载num10 let numnum5 echo $num # 15num本身变了 # 简写形式 num10 let num5 # num 15 let num-3 # num 12 let num*2 # num 24 let num # num 25自增 let num-- # num 24自减 let numnum**3 # num 13824幂运算5.3 bc浮点数计算expr只能算整数bc能算小数bash复制下载# 整数除法 echo $[10 / 3] # 3 # bc浮点运算 echo scale2; 10/3 | bc # 3.33保留2位小数 echo scale3; 10/3 | bc # 3.333 # 更多运算 echo 5^2 | bc # 25平方 echo sqrt(16) | bc # 4平方根 # 变量结合 r5 echo scale2; 3.14159 * $r * $r | bc # 78.53 # 逻辑运算返回0或1 echo 35 | bc # 0 echo 35 | bc # 1 本章总结Shell运算有四种方式——expr需空格和转义、[]简洁、[]简洁、(())最常用、let直接改变量。整数运算用[]或[]或(())累加累改用let浮点数必须用bc。记住日常用$[]累改用let小数用bc。第6章变量类型与作用范围6.1 自定义变量 vs 环境变量类型说明示例自定义变量用户自己定义的当前Shell私有name小明环境变量系统预定义的全局可用$USER、$HOME、$PATH常见环境变量bash复制下载echo $USER # 当前用户名 echo $HOME # 用户主目录 echo $PWD # 当前工作目录 echo $SHELL # 默认Shell echo $RANDOM # 随机数0-32767 echo $UID # 用户ID$PATH——命令搜索路径bash复制下载echo $PATH # 输出/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin # 临时添加脚本目录到PATH只在当前Shell生效 PATH$PATH:/root/myscripts test.sh # 现在可以直接运行了 # 注意千万不要 PATH会让所有命令失效6.2 只读变量不可修改bash复制下载# 定义时设置只读 readonly PI3.14159 PI3.14 # ✗ 报错readonly variable # 已有变量设为只读 MAX_RETRIES3 readonly MAX_RETRIES MAX_RETRIES5 # ✗ 报错 # 只读变量无法删除 unset PI # ✗ 报错cannot unset readonly6.3 位置变量获取脚本参数执行bash test.sh 张三 123456变量含义示例值$0脚本名称test.sh$1第一个参数张三$2第二个参数123456$#参数总数2$*所有参数整体张三 123456$所有参数独立张三 123456bash复制下载#!/bin/bash # 两数相加脚本bash add.sh 10 20 sum$(( $1 $2 )) echo $1 $2 $sum # 执行bash add.sh 10 20 → 输出10 20 306.4 预定义变量变量含义$?上一条命令的返回状态0成功非0失败$$当前进程的进程号$!最后一个后台进程的进程号bash复制下载# $? 判断命令是否成功 ls /etc/passwd echo $? # 0成功 ls /nonexistent echo $? # 非0失败 # 脚本中判断 tar -czf backup.tar.gz /etc/ if [ $? -eq 0 ]; then echo 备份成功 else echo 备份失败 fi6.5 export变量出国旅行默认变量只在当前Shell有效子Shell看不到bash复制下载name小明 bash # 进入子Shell echo $name # 无输出子Shell看不到 exit # 退出子Shell用export导出后子Shell也能看到bash复制下载export name # 导出变量 bash # 进入子Shell echo $name # 输出小明子Shell能看到 exit # 三种用法 export city北京 # 定义时直接导出 name张三; export name # 先定义再导出 export -n name # 取消导出 本章总结自定义变量私有环境变量公共。只读变量用readonly设置不可修改删除。位置变量$1、$2获取脚本参数$#统计参数个数。$?判断命令成功0或失败非0$$获取当前进程ID。用export导出变量让子Shell也能访问。记住私有用export变公有只读用readonly成功看$?。第7章重定向与管道——数据流的艺术7.1 三条流水线文件描述符名称默认设备说明0STDIN键盘程序从这里读数据1STDOUT显示器正常输出到这里2STDERR显示器错误信息到这里7.2 输出重定向bash# 覆盖写入会覆盖原有内容 uname -p kernel.txt # 追加写入追加到文件末尾 uname -r kernel.txt # 分离正确和错误输出 ls /etc/passwd xxx ok.txt 2 err.txt # /dev/null数据黑洞忽略所有输出 make /dev/null 21 # 静默编译啥都不显示7.3 输入重定向与Here Documentbash# 从文件读取 cat 1.txt # 等价于 cat 1.txt # Here Document多行输入 cat EOF 第一行 第二行 第三行 EOF # 输出到配置文件 cat EOF config.txt app_nameMyApp version1.0 EOF # 非交互式设置密码 echo 123456 pass.txt passwd --stdin jerry pass.txt7.4 管道把命令串起来text命令1的输出 → 命令2的输入 → 命令3的输入 → 最终结果常用管道命令命令功能示例grep过滤cat file | grep errorsort排序cat file | sort -nuniq去重/统计cat file | uniq -cwc统计行/字/字符cat file | wc -lcut提取列cat file | cut -d: -f1bash# 查找httpd包 rpm -qa | grep httpd # 统计当前登录用户数 who | wc -l # 统计访问量最高的10个IP日志分析 cat access.log | awk {print $1} | sort | uniq -c | sort -rn | head -10 # awk取IP → sort排序 → uniq统计 → sort倒序 → head取前10 # 提取bash用户 cat /etc/passwd | grep /bin/bash$ | cut -d: -f1 # grep过滤bash用户 → cut取用户名 本章总结Linux有三条标准通道——0输入、1正确输出、2错误输出。重定向用覆盖、追加、2分离错误。/dev/null是数据黑洞用来忽略不需要的输出。管道|把多个命令串联起来实现复杂数据处理。常用管道命令grep过滤、sort排序、uniq去重统计、wc统计、cut提取列。记住覆盖追加2分离错误|串联命令。第8章综合实战——三个经典脚本实战1服务器健康检查bash#!/bin/bash echo 服务器健康检查 echo 时间$(date %Y-%m-%d %H:%M:%S) echo echo 【系统信息】 echo 主机名$(hostname) echo 运行时间$(uptime -p 2/dev/null || who -b | awk {print $3 $4}) echo echo 【CPU负载】 uptime echo echo 【内存】 free -h echo echo 【磁盘】 df -hT | grep -v tmpfs echo echo 【服务状态】 for s in sshd nginx httpd mysql; do if systemctl is-active $s /dev/null; then echo ✓ $s: 运行中 else echo ✗ $s: 未运行 fi done实战2日志备份清理bash#!/bin/bash BACKUP_DIR/backup/logs DATE$(date %Y%m%d_%H%M%S) mkdir -p $BACKUP_DIR tar -czf ${BACKUP_DIR}/logs_${DATE}.tar.gz /var/log/*.log 2 ${BACKUP_DIR}/error.log if [ $? -eq 0 ]; then echo ✓ 备份成功${BACKUP_DIR}/logs_${DATE}.tar.gz # 清理7天前的旧备份 find $BACKUP_DIR -name logs_*.tar.gz -mtime 7 -delete echo ✓ 已清理7天前的旧备份 else echo ✗ 备份失败 fi实战3批量创建用户从文件读取users.txt格式textzhangsan:123456:技术部 lisi:654321:市场部 wangwu:888888:人事部脚本bash#!/bin/bash while IFS: read -r username password dept; do [ -z $username ] continue # 跳过空行 if id $username /dev/null; then echo △ $username 已存在 else useradd -m -c $dept $username echo $username:$password | chpasswd echo ✓ $username 创建成功$dept fi done users.txt 本章总结三个实战脚本涵盖了运维的典型场景——健康检查系统信息采集、备份清理tar打包find清理、批量用户管理文件读取循环处理。这些脚本综合运用了变量、命令替换、重定向、管道、条件判断if、循环for/while、位置参数等前面所有章节的知识。学完本章你应该能独立编写简单的自动化运维脚本了。总复习速查表章节核心要点一句话总结第1章Shell是翻译官脚本是命令清单Shell连接用户和内核第2章四步创建脚本创建→授权→检查→执行写脚本用./测脚本用bash第3章变量定义无空格引用加$定义无空格引用用$第4章双引号识别变量单引号原样输出双引号活单引号死第5章$[]日常用bc算小数let做累加整数用$[]小数用bc第6章私有用export变公有$?判断成功export变全局$?判成败第7章覆盖追加|串联命令重定向控流向管道串命令第8章综合运用写实战脚本学以致用自动运维