当前位置: 首页 > news >正文

2.Shell脚本修炼手册---创建第一个 Shell 脚本

2. 创建第一个 Shell 脚本

文章目录

    • 2. 创建第一个 Shell 脚本
      • 2.1 什么是 Shell 脚本?
        • 2.1.1 脚本开头:告诉系统用什么程序执行
        • 2.1.2 脚本注释:给人看的 “说明书”
        • 2.1.3 bash 与 sh 的区别
      • 2.2 如何执行 Shell 脚本?
        • 方法 1:用 bash 或 sh 命令执行(推荐新手)
        • 方法 2:直接用路径执行(需要执行权限)
        • 方法 3:用 source 或。执行(影响当前终端)
        • 方法 4:用输入重定向或管道执行
      • 2.3 Shell 脚本开发的规范和好习惯
        • 基本规范
        • 好习惯
      • 2.4 综合实验(初次体验shell脚本的高效率):写一个系统检查脚本
        • 实验流程
        • 详细步骤
          • 步骤 1:创建脚本文件
          • 步骤 2:编写脚本内容
          • 步骤 3:给脚本加执行权限
          • 步骤 4:执行并验证结果

2.1 什么是 Shell 脚本?

简单来说,Shell 脚本就是把一系列 Linux 命令、Shell 控制语句(比如判断、循环)和注释写到一个文件里,让系统按顺序执行。就像我们写购物清单,一条条列好要买的东西,然后按清单去采购一样。

在 Linux 里,推荐用 vim 编辑器写脚本(功能比 vi 更强大)。如果习惯了输入 vi 命令,可以给 vi 起个别名指向 vim,这样输入 vi 就会自动打开 vim,设置方法如下:

# 把别名配置写入系统bash配置文件(/etc/bashrc),永久生效
[root@shell ~]# echo "alias vi='vim'" >> /etc/bashrc
# 让刚写入的配置立即生效(不用重启终端)
[root@shell ~]# source /etc/bashrc

小贴士:source 文件名 也可以写成 . 文件名(一个点),作用是在当前终端直接执行文件里的命令,而不是开一个新窗口执行。这样文件里的变量、别名等设置会直接影响当前终端。

2.1.1 脚本开头:告诉系统用什么程序执行

一个规范的 Shell 脚本第一行必须写清楚:用哪个程序(解释器)来执行这个脚本。就像我们看视频前要知道用播放器还是浏览器打开一样。

在 Linux bash 编程里,通常这样写:

#!/bin/bash 

或者

#!/bin/sh

这里的 #! 叫 “幻数”(不用记名字,知道作用就行),它的作用是告诉系统:“接下来的脚本内容,交给 #! 后面的程序(比如 /bin/bash)来执行”。

注意:这一行必须在脚本的最顶端(第一行),如果写在其他行,就会被当成普通注释,不会生效。

举个例子:

# 用vim创建一个叫script.sh的脚本
[bq@shell ~]$ vim script.sh
# 在脚本里写两行内容
#!/bin/bash  # 第一行:指定用bash解释器
echo "Hello World !"  # 第二行:输出一句话

在 CentOS 和 RHEL 系统里,默认的 Shell 就是 bash,所以就算不写第一行,系统也会用 bash 执行。但强烈建议加上,如果换了其他系统(比如默认 Shell 不是 bash),没这一行可能会出问题。养成规范的习惯总是好的~

2.1.2 脚本注释:给人看的 “说明书”

脚本里 # 后面的内容都是注释,系统不会执行,是写给人看的。就像给代码加备注,告诉自己或别人 “这段代码是干嘛的”。

注释可以单独占一行,也可以跟在命令后面:

# 这是单独一行的注释:检查磁盘使用情况
df -h  # 这是跟在命令后面的注释:显示磁盘使用情况(人类可读格式)

为什么要写注释?
如果脚本复杂,过几个月自己可能都忘了某段代码的作用;团队协作时,别人也看不懂你的脚本。所以关键步骤一定要加注释,尽量用英文(避免中文乱码)。

2.1.3 bash 与 sh 的区别

很多人会问:#!/bin/bash#!/bin/sh 有区别吗?

简单说,shbash 的 “简化版”(软链接),大部分情况下用哪个都一样。但为了规范,推荐用 #!/bin/bash

可以用这个命令看 shbash 的关系:

# 查看/bin/sh是什么(结果会显示它指向bash)
[bq@shell ~]$ ls -l /bin/sh
lrwxrwxrwx. 1 root root 4 112 17:33 /bin/sh -> bash

2.2 如何执行 Shell 脚本?

写好脚本后,怎么让它跑起来?Shell 脚本的执行流程很简单:从上到下依次执行每一行命令,遇到嵌套的子脚本就先执行子脚本,再回来继续执行父脚本。

常见的执行方法有 4 种,根据场景选着用:

方法 1:用 bash 或 sh 命令执行(推荐新手)

如果脚本没设置执行权限,或者没写第一行的解释器,用这种方法最稳妥。

# 格式:bash 脚本名  或  sh 脚本名
[bq@shell ~]$ bash script.sh  # 执行script.sh,输出Hello World!
Hello World!
方法 2:直接用路径执行(需要执行权限)

先给脚本加 “可执行权限”,然后通过绝对路径(全路径)或相对路径(当前目录下)执行。

# 第一步:给脚本加执行权限(+x表示增加执行权限)
[bq@shell ~]$ chmod +x script.sh# 第二步:执行脚本
# 用绝对路径(从根目录开始的完整路径)
[bq@shell ~]$ /home/bq/script.sh  
# 用相对路径(./表示当前目录)
[bq@shell ~]$ ./script.sh  
Hello World !

小贴士:企业里经常有人忘加执行权限导致脚本跑不了,所以如果不确定权限,用方法 1 更保险。

方法 3:用 source 或。执行(影响当前终端)

这种方法会在当前终端直接执行脚本,而不是开新进程。好处是:脚本里定义的变量、函数等,执行后在当前终端还能直接用。

# 格式:source 脚本名  或  . 脚本名(注意.后面有空格)
[bq@shell ~]$ source script.sh  
Hello World !
# 等效于
[bq@shell ~]$ . script.sh  
Hello World !
方法 4:用输入重定向或管道执行

通过 “把脚本内容传给 bash” 的方式执行,适合临时测试脚本。

# 把script.sh的内容作为输入传给bash
[bq@shell ~]$ bash < script.sh  
Hello World !# 用管道把脚本内容传给bash(和上面效果一样)
[bq@shell ~]$ cat script.sh | bash  
Hello World !

2.3 Shell 脚本开发的规范和好习惯

规范不是 “必须遵守的法律”,但能让脚本更好写、更好改、更好合作。就像写文章要分段、用标点,代码也要有规矩。

基本规范
  1. 第一行必须指定解释器
    开头写上 #!/bin/bash,明确告诉系统用什么程序执行。

  2. 开头加版本和版权信息
    方便别人知道脚本的作者、用途、版本等,比如:

    #!/bin/bash
    # Date:16:29 2022-3-30  # 脚本创建时间
    # Author:Created by bq  # 作者
    # Description:This script is used to check system status  # 用途
    # Version:2.0  # 版本号
    

    可以修改 ~/.vimrcvim 自动生成这些信息(具体方法可以查 vim 配置)。

  3. 尽量不用中文
    包括注释,避免换个系统就乱码。如果一定要用中文,在脚本里加 export LANG="zh_CN.UTF-8" 统一字符集。

  4. 脚本名以 .sh 结尾
    比如 system_check.sh,一眼就知道是 Shell 脚本。

  5. 存放在固定路径
    比如统一放在 /usr/local/scripts/,方便管理。

好习惯
  1. 成对符号一次性写
    {} [] '' "" 这些成对的符号,先写完一对再往里面填内容,避免漏写。比如先写 [],再退格在中间加内容。

  2. 中括号两端留空格
    [ 条件 ][[ 条件 ]] 时,括号和内容之间至少留一个空格,比如 if [ $a -eq 1 ](正确),别写成 if [$a -eq 1](错误)。

  3. 流程控制语句先写框架
    比如写 if 语句时,先把 if then fi 框架搭好,再填内容:

    if 条件;then# 这里填执行内容
    fi
    

    for 循环也一样:

    for 变量 in 列表;do# 这里填执行内容
    done
    
  4. 用缩进让代码易读
    像上面的 iffor,里面的内容缩进 2-4 个空格,一眼就能看出层次。

  5. 字符串变量加引号
    定义字符串变量时,值用双引号括起来(比如 name="zhangsan"),等号前后别留空格。如果需要 “原样输出”(不解析变量),用单引号(比如 echo 'Hello $name' 会输出 Hello $name)。命令的结果用反引号 ```或 $() 括起来(比如 today=$(date))。

  6. 符号用英文状态
    所有符号(引号、括号、逗号等)必须是英文的,中文符号会导致脚本报错。

2.4 综合实验(初次体验shell脚本的高效率):写一个系统检查脚本

实验流程
  1. 创建脚本文件 system_check.sh
  2. 编写脚本内容(实现文件系统、磁盘 IO、CPU、内存、网络的检查)
  3. 给脚本加执行权限
  4. 执行脚本并验证结果
详细步骤
步骤 1:创建脚本文件

vim 新建一个叫 system_check.sh 的文件:

[bq@shell ~]$ vim system_check.sh
步骤 2:编写脚本内容

i 进入编辑模式,写入以下内容:

#!/bin/bash
# 系统关键指标巡检脚本
# 检查内容:文件系统、磁盘IO、CPU、内存、网络使用情况# 确保脚本以root权限运行(很多系统命令需要root才能执行)
# id -u 会返回当前用户的ID,root用户的ID是0
if [ "$(id -u)" -ne 0 ]; then# 若不是root,输出错误信息(>&2表示把信息输出到错误通道),然后退出echo "请使用root权限运行此脚本 (sudo $0)" >&2exit 1  # 退出码1表示执行失败
fi# 定义颜色变量(让输出更醒目)
RED='\033[0;31m'      # 红色:错误/警告
YELLOW='\033[1;33m'   # 黄色:标题/重点
GREEN='\033[0;32m'    # 绿色:正常/成功
NC='\033[0m'          # 无颜色:重置终端颜色(避免后续输出都带颜色)# 输出报告标题
echo -e "\n============================================="  # -e 允许解析转义字符(如\n换行)
echo -e "          系统关键指标巡检报告                "
echo -e "          时间: $(date "+%Y-%m-%d %H:%M:%S")      "  # date命令输出当前时间
echo -e "=============================================\n"# 1. 检查文件系统使用情况
echo -e "1. ${YELLOW}文件系统使用情况${NC}"  # 用黄色显示标题,结束后重置颜色
echo "---------------------------------------------"
# df -h:以人类可读的格式(GB/MB)显示磁盘使用情况
# awk命令:保留第一行表头,其他行按第5列(使用率)从高到低排序
df -h | awk 'NR==1; NR>1 {print $0 | "sort -k5 -nr"}'# 检查是否有文件系统使用率超过85%(预警)
echo -e "\n${YELLOW}警告: 使用率超过85%的文件系统:${NC}"
# df -P:避免输出换行;awk处理:去掉百分号,筛选使用率>85%的行
df -P | awk 'NR>1 {gsub(/%/,""); if($5>85) print $0}'# 2. 检查磁盘IO使用情况
echo -e "\n\n2. ${YELLOW}磁盘IO使用情况${NC}"
echo "---------------------------------------------"
# 先检查iostat命令是否存在(需要安装sysstat包)
if command -v iostat &> /dev/null; then  # &> /dev/null表示不显示检查过程# iostat -x:显示详细IO统计;1 2:每隔1秒查1次,共查2次;tail取有效数据iostat -x 1 2 | tail -n +4
else# 若iostat不存在,提示安装sysstatecho "未安装sysstat包,无法获取磁盘IO信息。请安装:yum install sysstat 或 apt-get install sysstat"
fi# 3. 检查CPU使用情况
echo -e "\n\n3. ${YELLOW}CPU使用情况${NC}"
echo "---------------------------------------------"
echo "总体CPU使用率:"
# top -bn1:非交互式输出1次CPU信息;grep筛选CPU行;awk提取用户态、系统态、空闲率
top -bn1 | grep "Cpu(s)" | awk '{printf "用户态: %.2f%%, 系统态: %.2f%%, 空闲: %.2f%%\n", $2, $4, $8}'# 显示各CPU核心的使用详情
echo -e "\nCPU核心使用详情:"
# mpstat -P ALL:显示所有核心;1 1:查1次;tail取有效数据
mpstat -P ALL 1 1 | tail -n +4# 显示占用CPU最高的5个进程
echo -e "\n${YELLOW}占用CPU最高的5个进程:${NC}"
# ps -eo:指定输出格式(CPU使用率、PID、用户、命令);--sort=-%cpu:按CPU降序;head取前5个
ps -eo %cpu,pid,user,args --sort=-%cpu | head -n 6  # 6行包含表头# 4. 检查内存使用情况
echo -e "\n\n4. ${YELLOW}内存使用情况${NC}"
echo "---------------------------------------------"
# free -h:人类可读格式显示内存和swap使用
free -h# 显示内存详细统计
echo -e "\n内存使用详情:"
# vmstat -s:显示内存相关的统计数据(总内存、空闲、缓存等)
vmstat -s# 显示占用内存最高的5个进程
echo -e "\n${YELLOW}占用内存最高的5个进程:${NC}"
# ps -eo:输出内存使用率、物理内存(RSS)、PID等;按内存降序;取前5个
ps -eo %mem,rss,pid,user,args --sort=-%mem | head -n 6# 5. 检查网络使用情况
echo -e "\n\n5. ${YELLOW}网络使用情况${NC}"
echo "---------------------------------------------"# 显示网络接口流量
echo -e "\n${YELLOW}网络接口流量:${NC}"
# 优先用ifstat,没有则用iftop,都没有则显示基本网络信息
if command -v ifstat &> /dev/null; thenifstat 1 2  # 每隔1秒查1次,共2次
elif command -v iftop &> /dev/null; thenecho "按q退出iftop查看实时流量"sleep 2  # 等2秒再执行,给用户看提示iftop -n -t -s 5  # -n不解析主机名;-t文本模式;-s 5运行5秒退出
elseecho "未安装ifstat或iftop,显示网络接口配置:"# ip -s link show:显示接口状态;grep筛选已启动的接口ip -s link show | grep -A 2 "state UP"
fi# 显示网络连接情况(监听的端口)
echo -e "\n${YELLOW}网络连接统计:${NC}"
# netstat -tuln:显示TCP/UDP监听端口(不解析名称);排除本地回环地址
netstat -tuln | grep -v "127.0.0.1"  # 若提示netstat未找到,安装net-tools包# 统计各状态的TCP连接数
echo -e "\n${YELLOW}连接数统计:${NC}"
# 统计所有TCP连接的状态(如ESTABLISHED、LISTEN等)
netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'# 巡检完成提示
echo -e "\n\n============================================="
echo -e "          系统巡检完成                        "
echo -e "=============================================\n"

写完后按 Esc,输入 :wq 保存退出。

步骤 3:给脚本加执行权限
[bq@shell ~]$ chmod +x system_check.sh
步骤 4:执行并验证结果

用 root 权限执行(因为脚本里有检查权限的逻辑):

[bq@shell ~]$ sudo ./system_check.sh

执行后会看到类似以下的输出(根据系统状态不同,数值会变化):

=============================================系统关键指标巡检报告                时间: 2025-08-20 18:48:02      
=============================================1. 文件系统使用情况
---------------------------------------------
文件系统                 容量  已用  可用 已用% 挂载点
/dev/sda1               1014M  139M  876M   14% /boot
/dev/mapper/centos-root   50G  2.4G   48G    5% /
...警告: 使用率超过85%的文件系统:
(若没有超过85%的,这里为空)...(后续会显示磁盘IO、CPU、内存、网络的检查结果)...=============================================系统巡检完成                        
=============================================

注意:如果提示 netstat: 未找到命令,安装 net-tools 包即可(yum install net-toolsapt-get install net-tools)。

通过这个实验,你可以快速掌握 Shell 脚本的基本结构、执行方法和实用命令,以后可以根据需求扩展脚本功能(比如增加邮件报警、生成报告文件等)。
如涉及版权问题,请联系作者处理!!!!!!

http://www.dtcms.com/a/341842.html

相关文章:

  • C++ string类(reserve , resize , insert , erase)
  • 鸿蒙中网络诊断:Network分析
  • 深入理解JVM内存结构:从字节码执行到垃圾回收的全景解析
  • 金山云Q2营收23.5亿元 AI战略激活业务增长新空间
  • Altium Designer 22使用笔记(8)---PCB电气约束设置
  • GitHub Copilot - GitHub 推出的AI编程助手
  • Pytorch框架学习
  • Bigemap APP 详细使用教程,入门学习PPT
  • element table 表格多选框选中高亮
  • KubeBlocks for ClickHouse 容器化之路
  • 【运维进阶】shell三剑客
  • DeepSeek大模型如何重塑AI Agent?从技术突破到行业落地
  • 环境搭建-dockerfile构建镜像时apt软件包出现exit100错误+ pip下载python库时下载过慢的解决方法
  • SpringWeb详解
  • CorrectNav——基于VLM构建带“自我纠正飞轮”的VLN:通过「视觉输入和语言指令」预测导航动作,且从动作和感知层面生成自我修正数据
  • 【LeetCode热题100道笔记+动画】三数之和
  • Linux上安装MySQL 二进制包
  • TENON AI-AI大模型模拟面试官
  • idea进阶技能掌握, 自带HTTP测试工具HTTP client使用方法详解,完全可替代PostMan
  • 【力扣 买卖股票的最佳时机 Java/Python】
  • 数据库架构开发知识库体系
  • VGG改进(3):基于Cross Attention的VGG16增强方案
  • Foundry与Uniswap V2实战开发指南
  • 【自记】Power BI 中 DISTINCT 和 ALLNOBLANKROW 的区别说明
  • 比特分割 + 尖峰保留:FlashCommunication V2 实现任意比特通信与 3.2× 加速
  • 一键授权登录
  • Windows暂停更新10年最简单的设置
  • UNet改进(33):基于CBAM原理与PyTorch实战指南
  • 可信数据空间关键技术和功能架构研究
  • RAG流程全解析:从数据到精准答案