八、shell脚本

发布时间:2026/6/8 21:26:10

八、shell脚本 Linux入门到大神笔记https://blog.csdn.net/qq_58308926/category_13058048.html?fromshareblogcolumnsharetypeblogcolumnsharerId13058048sharereferPCsharesourceqq_58308926sharefromfrom_linkLinux企业实战练习https://blog.csdn.net/qq_58308926/category_13049591.html?fromshareblogcolumnsharetypeblogcolumnsharerId13049591sharereferPCsharesourceqq_58308926sharefromfrom_link一、Shell脚本概述1.1 什么是Shell脚本Shell脚本本质上是一个文件里面定义了多个Linux命令、变量以及逻辑控制判断、循环等实现自动化运维批量重复操作减少管理员工作量基于Linux命令解释性语言上手简单1.2 学习Shell脚本的前提熟悉Linux常用命令熟悉常用服务的部署与配置如Apache、Nginx、DNS等熟练文本处理工具grep、awk、sed熟悉Vim编辑器二、Shell脚本编写规范2.1 基本规范文件后缀以.sh结尾第一行声明解释器#!/bin/bash或#!/bin/sh注释使用#表示注释行不参与执行脚本开头建议包含信息#!/bin/bash # Author: 作者名 # Mail: 联系方式 # Date: 日期 # Describe: 脚本描述 # Warning: 警告信息 # Version: 版本号 # Modify: 修改记录代码缩进提高可读性尽量不使用中文注释避免编码问题2.2 快速生成注释模板.vimrc配置在~/.vimrc中添加以下内容新建.sh文件时自动生成头部注释autocmd BufNewFile *.py,*.cc,*.sh,*.java exec :call SetTitle() func SetTitle() if expand(%:e) sh call setline(1,#!/bin/bash) call setline(2,##############################################################) call setline(3, # File Name: .expand(%)) call setline(4, # Version: V1.0) call setline(5, # Author: yourname) call setline(6, # Email: youremail.com) call setline(7, # Created Time : .strftime(%F %T)) call setline(8, # Description:) call setline(9,##############################################################) call setline(10, ) endif endfunc2.3 注释方式单行注释以#开头多行注释使用EOF ... EOFEOF可替换为其他标识EOF 这是多行注释 不会被执行 EOF三、Shell脚本的执行方式3.1 四种执行方式方式语法是否需要x权限执行环境相对路径./script.sh需要子Shell绝对路径/root/script.sh需要子Shellsource或点source script.sh或. script.sh不需要需要r权限当前Shellbash/shbash script.sh或sh script.sh不需要需要r权限子Shell3.2 注意事项子Shell vs 当前Shell在子Shell中定义的变量、环境更改不会影响父Shell使用source或.执行时变量会在当前Shell中生效相对/绝对路径执行需要给脚本添加执行权限chmod ax script.sh四、变量与参数4.1 位置化变量位置参数用于在执行脚本时传入参数变量含义$0脚本文件本身的名字$1第一个参数$2第二个参数......${10}第十个及以上参数需用花括号示例创建用户并设置密码的脚本#!/bin/bash # useradd.sh useradd $1 echo $2 | passwd --stdin $1执行./useradd.sh zhangsan redhat4.2 预定义变量变量含义$?上一条命令的退出状态码0成功非0失败$#传递给脚本的参数个数$*所有参数作为一个字符串$所有参数每个作为独立字符串$$当前Shell进程的PID4.3 read命令 – 从键盘读取输入语法read [选项] [变量名]选项说明-p 提示信息输出提示信息-s隐藏输入常用于密码-t 秒数超时自动跳过不指定变量名数据存入环境变量REPLY示例#!/bin/bash read -p 请输入用户名: username read -s -p 请输入密码: password useradd $username echo $password | passwd --stdin $username echo $username 创建成功密码已设置4.4 exit命令直接执行exit会退出当前终端或脚本在脚本中遇到exit立即终止脚本exit n指定退出码n为数字0表示成功1-255表示失败退出码可通过echo $?查看示例检查密码中是否包含连续数字12345若包含则退出#!/bin/bash read -p 请输入密码: pass echo $pass | grep 12345 -q if [ $? -eq 0 ]; then echo 密码不能包含12345 exit 1 fi echo 密码合法五、逻辑运算符与复合指令5.1 逻辑运算符运算符含义规则逻辑与前一条命令成功返回0才执行后一条!逻辑非对返回状态取反示例# 创建用户并设置密码 useradd luojiyu echo 1 | passwd --stdin luojiyu # 如果用户存在则修改密码否则创建 useradd devops || echo 1 | passwd --stdin devops # 判断IP是否通根据结果写入不同文件 ping -c4 10.10.10.1 /dev/null echo 10.10.10.1 /opt/ip-ok.txt || echo 10.10.10.1 /opt/ip-error.txt5.2 复合指令;顺序执行多条命令无条件执行所有命令command1; command2; command3(命令;命令)在子Shell中执行括号开头不需要空格最后命令不用分号(cd /tmp; pwd){ 命令;命令; }在当前Shell中执行花括号开头必须有空格每条命令以分号结尾{ cd /tmp; pwd; }六、条件测试语句条件测试用于判断表达式的真假返回值为0表示真非0表示假。6.1 三种测试语法语法说明test 条件表达式常用在终端临时测试[ 条件表达式 ]脚本中常用注意空格[[ 条件表达式 ]]支持正则和通配符更强大示例test root 123 ; echo $? # 返回1 [ 1 -eq 1 ]; echo $? # 返回0 [[ abc a* ]]; echo $? # 支持通配符返回06.2 文件属性运算符运算符含义-e 文件文件存在-f 文件是普通文件-d 文件是目录-s 文件文件非空-r 文件可读-w 文件可写-x 文件可执行-L 文件是链接文件示例# 如果/tmp/passwd不存在则拷贝 [ -e /tmp/passwd ] || cp /etc/passwd /tmp/passwd # 如果useradd有执行权限则拷贝并修改所有者 [ -x /usr/sbin/useradd ] cp /usr/sbin/useradd /tmp chown devops /tmp/useradd # 如果文件没有读权限则添加 [ -r /tmp/passwd ] || chmod ar /tmp/passwd6.3 数字比较运算符运算符含义-eq等于-ne不等于-gt大于-ge大于等于-lt小于-le小于等于注意不要使用数学符号、等在条件测试中它们会被解释为重定向示例判断根分区使用率是否超过10%disk_num$(df | grep -w / | awk {print $5} | tr -d %) if [ $disk_num -ge 10 ]; then rm -rf /tmp/* echo tmp目录已清空 else echo disk free使用率: ${disk_num}% fi6.4 字符串比较运算符运算符含义或相等!不等-z 字符串字符串为空长度0-n 字符串字符串非空示例# 判断输入是否为root read -p 输入用户名: name [ $name root ] echo UID: $(id -u root) || exit # 检查参数是否为空 [ -z $1 ] echo 请传入参数 || echo 参数是: $16.5 布尔运算符用于[ ]中运算符含义-a逻辑与AND-o逻辑或OR!逻辑非在[[ ]]中可使用、||、!更直观。示例# 用户名是zhangsan 且 UID1000 [ $username zhangsan -a $useruid -ge 1000 ] echo ok || echo error # 使用[[ ]] [[ $username zhangsan $useruid -ge 1000 ]] echo ok七、判断语句7.1 if单分支语法if 条件表达式; then 执行语句 fi # 第二种写法 if 条件表达式 then 执行语句 fi示例用户已存在则退出#!/bin/bash read -p 输入用户名: name if id $name /dev/null; then echo $name 已存在不能创建 exit fi useradd $name7.2 if双分支语法if 条件表达式; then 语句1 else 语句2 fi示例用户存在则重置密码否则创建#!/bin/bash read -p 输入用户名: name if id $name /dev/null; then read -p 重置密码: pass echo $pass | passwd --stdin $name else useradd $name echo 1 | passwd --stdin $name fi示例备份脚本判断目录是否存在#!/bin/bash read -p 要备份的文件路径: src read -p 备份目录路径: dst if [ -d $dst ]; then chmod 777 $dst else mkdir $dst fi cp -a $src $dst/$(basename $src)-$(date %F).bak7.3 if多分支语法if 条件1; then 语句1 elif 条件2; then 语句2 else 语句3 fi示例成绩等级判断read -p 请输入成绩(0-100): score if [ $score -ge 85 ]; then echo 优秀 - A elif [ $score -ge 70 ]; then echo 良好 - B elif [ $score -ge 60 ]; then echo 合格 - C else echo 不合格 - D fi7.4 case多分支用于多值匹配比多个elif更清晰。语法case 变量 in 模式1) 命令 ;; 模式2) 命令 ;; *) 默认命令 ;; esac示例成绩等级case版本read -p 请输入成绩(0-100): score case $score in 8[5-9]|9[0-9]|100) echo 优秀 - A ;; 7[0-9]|8[0-4]) echo 良好 - B ;; 6[0-9]) echo 合格 - C ;; *) echo 不合格 - D ;; esac模式支持|表示或[0-9]表示范围*表示任意八、循环语句8.1 for循环语法for 变量名 in 列表; do 命令 done四种列表生成方式# 1. 直接列出 for i in 1 2 3 4 5; do echo $i; done # 2. 大括号支持数字和字母 for i in {1..5}; do echo $i; done for c in {a..z}; do echo $c; done # 3. seq命令 for i in $(seq 1 5); do echo $i; done # 4. 命令执行结果 for file in $(ls *.sh); do echo $file; doneC语言风格for循环for ((i1; i10; i)); do echo $i done示例1批量创建用户从文件读取for user in $(cat userlist.txt); do useradd $user echo 123456 | passwd --stdin $user done示例2扫描局域网在线主机for i in {1..254}; do ip192.168.1.$i ping -c2 -W1 $ip /dev/null if [ $? -eq 0 ]; then echo $ip is up else echo $ip is down fi done8.2 while循环当条件为真时循环条件为假时退出。语法while 条件表达式; do 命令 done示例读取文件每一行三种方式# 方式1exec重定向 exec file.txt while read line; do echo $line done # 方式2管道 cat file.txt | while read line; do echo $line done # 方式3重定向结尾推荐 while read line; do echo $line done file.txt示例从iplist文件读取IP和端口# iplist内容 # 192.168.1.101 22 # 192.168.1.102 80 while read line; do IP$(echo $line | awk {print $1}) PORT$(echo $line | awk {print $2}) echo IP: $IP, PORT: $PORT done iplist8.3 until循环与while相反条件为假时进入循环为真时退出。语法until 条件表达式; do 命令 done示例等待某个文件出现until [ -f /tmp/ready ]; do echo 等待文件... sleep 2 done echo 文件已出现8.4 break和continuebreak立即跳出当前循环continue跳过本次循环剩余语句进入下一次迭代示例# break: 当i4时跳出 for i in {1..10}; do if [ $i -eq 4 ]; then break fi echo $i done # 输出: 1 2 3 # continue: 当i4时跳过 for i in {1..10}; do if [ $i -eq 4 ]; then continue fi echo $i done # 输出: 1 2 3 5 6 7 8 9 10九、综合实践案例9.1 一键部署Nginx脚本框架#!/bin/bash # 检查是否root用户 if [ $EUID -ne 0 ]; then echo 请使用root用户执行 exit 1 fi # 安装依赖 yum install -y gcc make pcre-devel zlib-devel # 下载并编译安装Nginx cd /usr/local/src wget http://nginx.org/download/nginx-1.24.0.tar.gz tar xf nginx-1.24.0.tar.gz cd nginx-1.24.0 ./configure --prefix/usr/local/nginx make make install # 启动 /usr/local/nginx/sbin/nginx echo Nginx部署完成9.2 安全创建用户脚本#!/bin/bash read -p 请输入用户名: username if id $username /dev/null; then echo 用户已存在 exit 1 fi read -s -p 请输入密码: password read -s -p 确认密码: password2 echo if [ $password ! $password2 ]; then echo 两次密码不一致 exit 1 fi useradd $username echo $password | passwd --stdin $username /dev/null echo 用户 $username 创建成功9.3 系统监控脚本#!/bin/bash # 监控CPU、内存、磁盘使用率 cpu$(top -bn1 | grep Cpu(s) | awk {print $2} | cut -d% -f1) mem$(free | grep Mem | awk {printf %.2f, $3/$2 * 100}) disk$(df -h / | awk NR2 {print $5} | tr -d %) echo CPU使用率: $cpu% echo 内存使用率: $mem% echo 根分区使用率: $disk% if [ $disk -gt 80 ]; then echo 警告磁盘空间不足 fi十、总结知识点核心要点编写规范#!/bin/bash, 注释, .sh后缀执行方式路径需x权限source在当前shell其他在子shell位置变量1...{10}特殊变量#参数个数read-p提示-s隐藏-t超时条件测试[ ]文件 -f/-d数字 -eq/-gt字符串 /-z逻辑符成功则执行||失败则执行判断if单/双/多分支case多值匹配循环for列表/C风格while条件真循环until条件假循环控制break跳出continue跳过本次掌握以上内容即可编写大部分日常运维所需的Shell脚本。实践中多动手、多调试利用set -x调试模式查看执行过程。

相关新闻