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

Linux中的Shell脚本基础

一、什么是Shell脚本

Shell 脚本是一种用 Shell 命令编写的脚本程序,用于在 Unix/Linux 系统的命令行环境中自动化执行任务
它由一系列命令、逻辑控制语句(如条件判断、循环)和函数组成,保存为文本文件(通常以 .sh 为扩展名),由 Shell 解释器(如 Bash、Zsh)逐行解析执行。

Shell 脚本的核心特点

  1. 基于命令行:直接调用系统命令(如 lsgrepawk),无需编译。

  2. 轻量级:适合快速开发小型自动化任务。

  3. 跨平台性:在支持相同 Shell 的系统(如 Linux、macOS)中通用。

示例

#!/bin/bash
# 这是一个简单的 Shell 脚本
echo "Hello World!"  # 输出文本
mkdir backup         # 创建目录
cp *.txt backup/     # 复制所有 txt 文件到 backup 目录

二、Shell脚本存在的意义

Shell 脚本的主要意义是提升效率实现自动化,尤其在系统管理、运维、数据处理等领域中不可或缺。

核心价值

  1. 自动化重复操作

    • 例:批量重命名文件、定期清理日志、自动备份数据。

    • 替代手动逐条输入命令,减少人为错误。

  2. 简化复杂任务

    • 例:一键部署服务、集成多步骤流程(如下载数据 → 处理 → 上传结果)。

    • 通过逻辑控制(如 iffor)组合多个命令。

  3. 系统管理与监控

    • 例:检查磁盘空间、监控进程状态、发送报警邮件。

    • 直接调用系统工具(如 dfpscron)。

  4. 快速原型开发

    • 例:临时测试某个功能或流程。

    • 无需编译,修改后立即运行。

Shell脚本与其他编程语言的对比

场景Shell 脚本Python/Perl
文件操作直接调用 grepsedawk,语法简洁需要导入库,代码量稍多
系统命令交互无缝执行命令,无需额外封装需通过 subprocess 等模块调用
复杂逻辑/数据处理适合简单逻辑,复杂场景代码可读性差支持面向对象、数据结构,更易维护
性能要求适合轻量级任务,频繁启动子进程效率较低适合计算密集型任务

Shell 脚本的典型应用场景:

  1. 日常运维:自动化日志切割、清理过期文件、服务状态监控。

  2. 部署与发布:一键编译代码、打包应用、更新服务器。

  3. 数据处理:批量转换文件格式、提取文本内容、生成统计报表。

  4. 开发辅助:运行测试用例、生成文档、环境配置。

三、Shell脚本中的基本元素

Shell 脚本的基本元素是构建自动化任务和逻辑流程的核心组成部分。

脚本的基本结构

1. Shebang声明(也可以叫脚本幻数)(必选)

#!/bin/bash
  • 作用:指定脚本解释器路径(例如#!/bin/bash#!/usr/bin/bash

  • 必须放在脚本第一行,且Shebang 声明前不能有任何字符(包括空格、空行),否则会被忽略,可能被当作普通文本执行。

  • 脚本幻数(Shebang) 是计算机领域中对脚本文件首行 #! 声明的俗称,也被直接称为 “Shebang 声明”(读作 "hash-bang")。它是脚本文件的身份标识与执行指令,核心作用是告诉操作系统:“这个脚本需要用哪个解释器来运行”。

(1) Shebang 的本质
  • 不是解释器本身:Shebang(#!)本身只是一个指令前缀,用于告诉操作系统使用哪个解释器来执行脚本

  • 举例

    • #!/bin/bash:指定用 bash 解释器执行脚本。

    • #!/usr/bin/python3:指定用 Python 3 解释器执行脚本。

(2) Shebang 的工作流程

当执行脚本(如 ./script.sh)时,操作系统按以下步骤处理:

  1. 读取文件首行:检查是否包含 #!

  2. 解析解释器路径:提取 #! 后的路径(如 /bin/bash)。

  3. 启动解释器:将脚本路径作为参数传递给该解释器,由解释器逐行执行脚本内容

    • 关键点:Shebang 仅负责触发解释器,而解释命令的实际工作由解释器完成

(3) 常见误区澄清
误区正解
“Shebang 是解释器”Shebang 是指向解释器的指令,解释器是 /bin/bash 等具体程序
“Shebang 解释脚本命令”解释命令的是解释器程序(如 bash),而非 Shebang 本身
“Shebang 是脚本的一部分”Shebang 是由操作系统内核处理的元指令,不会传递给解释器
(4) 类比理解
  • Shebang 类似钥匙:告诉系统“用哪把钥匙(解释器)打开这把锁(脚本)”。

  • 解释器 类似锁匠:真正执行解锁(解释命令)操作的是锁匠(如 bash)。


2. 注释说明(推荐使用)

# 脚本功能:备份日志文件
# 作者:YourName
# 创建时间:2023-10-01
  • 单行注释用#

  • 多行注释可通过<<EOF...EOF: "..." 实现

  • 示例:


3. 变量定义(可选但常用)

LOG_DIR="/var/log"
BACKUP_DIR="/backup"
TODAY=$(date +%Y%m%d)  # 获取当前日期

4. 主逻辑代码(核心)

(1) 基础命令
echo "开始备份日志..."  # 输出信息
cp -v $LOG_DIR/*.log $BACKUP_DIR/${TODAY}_logs/
(2) 流程控制
if [ -d "$BACKUP_DIR" ]; thenecho "备份目录存在"
elsemkdir -p "$BACKUP_DIR"
fifor file in $LOG_DIR/*.log; dogzip "$file"
done
(3) 函数定义(可选)
clean_old_backups() {find $BACKUP_DIR -name "*.log.gz" -mtime +7 -delete
}
clean_old_backups  # 调用函数

5. 退出状态码(推荐使用)

exit 0  # 0表示成功,非0表示失败(通常1-255)

四、脚本的书写规范 

1. 书写规范注意事项

规范项关键要点
文件名

脚本文件名应见名知意明确体现功能,如 backup_mysql.sh --> 就是备份数据库的脚本。

Shebang声明

(脚本幻数)

首行必须指定脚本解释器,例如 #!/bin/bash 或 #!/usr/bin/env bash。
注释

使用英文注释,尽量不要用中文注释,防止本机或切换系统环境后中文乱码的困扰,文件开头加创建日期、作者、版本、用途等信息。

内部命令优先使用 echoeval 等内置命令,减少外部命令调用(避免频繁创建子进程)。
代码简化组合命令,减少冗余操作。

组合命令:通过管道、逻辑符 && 或 || 减少代码行数。

缩进与结构统一缩进,体现代码结构,增强可读性。
错误处理

启用 set -euo pipefail 严格模式(错误退出、未定义变量报错、管道错误检测)。

-eerrexit):遇到错误立即退出

-unounset):检查到未定义变量时报错并终止

-o pipefail:管道命令的严格错误处理

2. 使用vim命令书写脚本的设定

Vim 自动编写脚本主属性信息的配置方法

~/.vimrc 是 Vim 编辑器的用户配置文件,用于自定义 Vim 的行为、快捷键、插件、界面样式等。它位于用户的主目录(~)下,是 Vim 的核心配置文件。

通过 Vim 的 模板自动插入功能,可以在新建脚本时自动生成固定格式的头部信息(如作者、日期、描述等)。以下是详细配置步骤及示例:

(1)理解 ~/.vimrc这个文件的核心作用

.vimrc 的核心作用

功能示例配置说明
基础设置set number显示行号
语法高亮syntax on启用代码语法高亮
缩进控制set tabstop=4设置制表符为 4 个空格
快捷键映射nnoremap <C-s> :w<CR>按 Ctrl + S 保存文件
插件管理call plug#begin('~/.vim/plugged')声明插件管理器(如 vim-plug)
自动命令autocmd BufNewFile *.sh 0r ~/.vim/templates/shell_header.tpl

新建文件时加载模板。

较难理解的示例配置解析:

1、nnoremap <C-s> :w<CR>

该命令由三部分组成:

  • nnoremap:表示在普通模式(Normal Mode) 下创建一个非递归映射noremap 会禁止映射中调用其他映射,避免递归循环)。

  • <C-s>:触发映射的快捷键,即 Ctrl + s<C> 代表 Ctrl 键,<s> 代表 s 键)。

  • :w<CR>:映射执行的命令,:w 是 Vim 中保存文件的命令,<CR> 表示按下回车键(CR 是 Carriage Return 的缩写)。

2、call plug#begin('~/.vim/plugged')

该命令由三部分组成:

  • call:Vimscript 中调用函数的关键字。

  • plug#begin(...):Vim-Plug 提供的函数,用于初始化插件管理器。

  • '~/.vim/plugged':参数,表示插件的安装目录。Vim-Plug 会将所有插件下载到这个目录下。

3、autocmd BufNewFile *.sh 0r ~/.vim/templates/shell_header.tpl

该命令由三部分组成:

  • autocmd:Vim 的自动命令关键字,用于在特定事件发生时自动执行命令。

  • BufNewFile *.sh:触发自动命令的事件,表示新建一个以.sh结尾的文件时执行后续命令。

  • 0r ~/.vim/templates/shell_header.tpl:执行的命令,0r 表示在文件的第 0 行(即文件开头)读取并插入指定文件的内容,这里读取的是 ~/.vim/templates/shell_header.tpl 文件。

(2)配置 Vim 编辑器的用户配置文件

五、脚本执行方法

测试脚本内容:

[root@sakura1 桌面]# vim lee.sh
#!/bin/bash
cat

1、两种环境下运行脚本

(1)在当前环境下运行

(2)在指定环境中运行

通过路径来执行脚本时需要脚本文件有执行权限。

2、执行方式对比

执行方式命令示例是否需要执行权限进程树表现执行环境
1. 当前Shell环境. lee.sh &bash → cat当前Shell进程
source lee.sh &bash → cat当前Shell进程
2. 新建子Shellsh lee.sh &bash → sh → cat新建子Shell
3. 路径执行/root/lee.sh &需要bash → /bin/bash → cat新建子Shell

3、关键原理解析

  1. source 与 . 命令

    • 直接在当前Shell进程内执行脚本

    • 脚本中的 cat 成为当前Shell的子进程(无中间进程)

    • 无需执行权限(文件只需读权限)

  2. sh script.sh

    • 启动新 /bin/sh 进程解释脚本

    • sh 进程作为当前Shell的子进程,cat 成为 sh 的子进程

    • 无需执行权限(sh 作为解释器读取文件)

  3. 路径执行 (/path/to/script)

    • 依赖 Shebang 行 (#!/bin/bash) 选择解释器

    • 需要执行权限 (chmod +x)

    • 进程树:当前Shell → /bin/bash → cat

4、后台执行 (&) 现象

  • 阻塞进程的处理
    脚本中的 cat 会持续等待输入,导致进程进入 T 状态(暂停/后台阻塞):

    PID TTY STAT TIME COMMAND
    17890 pts/2 T   0:00 /bin/bash /root/lee.sh  # T = Stopped,父进程被阻塞
    17891 pts/2 T   0:00 \_ cat                  # 子进程同样阻塞
  • 恢复方法
    用 fg 切回前台输入,或发送 SIGCONT 信号 (kill -CONT PID)

六、脚本调试

测试脚本:

[root@timinglee ~]# vim lcf.sh
#!/bin/bash
hostname
echo $USER
date
cat     #这行的命令应为cal显示系统日历,这里是故意打错导致脚本错误,用来进行脚本调试展示
pwd

1、直接执行测试脚本的效果

脚本突然就卡住了,不能清晰的看出脚本的错误在哪里。

2、显示测试脚本执行过程的效果

明显可见脚本在执行到cat命令的时候因为cat命令没有写完整而导致了脚本被卡在cat命令这一步。

七、命令退出值

1、什么是退出值(Exit Status)

  • 定义:每个命令执行后返回的整数状态码(0-255)

  • 含义

    • 0:成功执行

    • 1-255:执行失败(不同值代表不同错误类型)

  • 重要性:Shell脚本中常用退出值判断命令执行结果

2、怎么查看和修改退出值

(1)查看退出值

# 查看上一个执行命令的退出值
echo $?

示例: 

(2)修改退出值(在脚本中进行操作)

方法一:使用 exit 命令

在脚本中显式设置退出值:

#!/bin/bash
# 脚本内容...
exit 5  # 设置退出值为5

示例:

方法二:通过命令返回值

使用最后执行命令的返回值:

#!/bin/bash
grep "pattern" file.txt  # 如果grep失败,自动返回非0值---当 grep 未找到匹配或出错时,
脚本会继承其非 0 退出状态,无需手动处理。
# 无需显式exit,自动继承grep的退出值---脚本的最终退出状态等于最后一条命令(grep)的退出
状态,无需添加exit语句。
  • grep "pattern" file.txt

    • 核心命令:在file.txt中搜索包含 "pattern" 的行。
    • grep 的退出状态
      • 找到匹配行时返回0(成功);
      • 文件存在但无匹配时返回1
      • 发生错误(如权限问题)或文件不存在时返回2

示例:

下图为file文件内的内容

退出值为0的情况:

退出值为1的情况:

退出值为2的情况:

相关文章:

  • 2025年5月通信科技领域周报(5.19-5.25):太赫兹通信规模商用启动 空天地一体化网络加速落地
  • 亚古数据:查询BVI(英属维尔京群岛)公司可以获取到什么信息和文件?
  • Cesium实现标注动画
  • get_rga_thread线程和low_camera_venc_thread线程获取低分辨率VENC码流数据
  • WES(二)——数据预处理
  • 美颜SDK功能模块化设计实战:滤镜、贴纸与人脸识别的协同实现
  • YOLOv8 区域计数系统:基于计算机视觉的智能物体计数方案
  • 各类效果名称收集
  • Nacos 服务注册发现案例:nacos-spring-cloud-example 详解
  • Django实现文件上传
  • 数据结构 -- 树相关面试题
  • 网络出版服务许可证年检
  • go实例化结构体的方式
  • 无法发布到PowerBI?试试拆分它
  • 天数计算卡 报错和解决记录
  • 玻纤效应的时序偏差
  • 有无D6完全是两个强度的主角——以撒(Isaac)
  • 基于Springboot + vue3实现的图书管理系统
  • 时间序列预测算法中的预测概率化笔记
  • Tesseract 字库介绍与训练指南
  • 小米网站建设/做竞价推广大概多少钱
  • 南昌网站建设信息/百度爱采购推广一个月多少钱
  • 时尚类网站建设/seo教程技术
  • 网站官方认证怎么做/网站推广的方式有哪些?
  • 东南亚做网站 什么语言/国外域名注册
  • 前端网站制作教程/网络营销软件网站