Shell 脚本编程全面学习指南

前言

Shell 脚本编程是 Linux 和 Unix 系统管理、自动化任务的核心工具之一。通过 Shell 脚本,你可以自动化重复性操作、简化复杂流程、提高系统管理效率,甚至构建完整的自动化运维工具。本文将带你从基础到进阶,全面学习 Shell 脚本编程,涵盖语法、结构、调试、最佳实践等内容。


一、Shell 简介与环境搭建

1.1 什么是 Shell?

Shell 是命令行解释器,是用户与操作系统内核之间的桥梁。它接收用户输入的命令,并调用相应的程序或服务来执行。

常见的 Shell 有:

  • Bash(Bourne-Again Shell):Linux 系统默认的 Shell,广泛使用。
  • sh(Bourne Shell):早期的 Unix Shell,兼容性好。
  • zsh(Z Shell):功能更强大、交互性更强的现代 Shell。
  • PowerShell:Windows 和跨平台环境下使用的 Shell,语法不同但功能类似。

本文以 Bash 为例进行讲解。

1.2 环境准备

在 Linux 或 macOS 系统中,Bash 通常已经预装。可以通过以下命令查看当前 Shell:

echo $SHELL

如果你使用的是 Windows,可以安装:

  • Windows Subsystem for Linux (WSL):推荐使用 WSL2,支持完整的 Linux 环境。
  • Git Bash:轻量级的 Bash 环境,适合开发人员。

二、第一个 Shell 脚本

2.1 编写脚本

创建一个名为 hello.sh 的文件:

#!/bin/bash
# 这是我的第一个 Shell 脚本echo "Hello, World!"

2.2 执行脚本

给脚本添加执行权限:

chmod +x hello.sh

执行脚本:

./hello.sh

2.3 解释 shebang

#!/bin/bash 被称为 shebang,用于告诉系统该脚本应使用哪个解释器来执行。不同的 shebang 可以指定不同的 Shell,例如:

  • #!/bin/sh:使用 Bourne Shell
  • #!/usr/bin/env python:使用 Python 解释器运行脚本

三、Shell 脚本基础语法

3.1 变量定义与使用

Shell 中变量不需要声明类型,赋值时等号两侧不能有空格:

name="Qwen"
echo "Hello, $name"

可以使用 ${name} 来避免歧义:

echo "Hello, ${name}_user"

3.2 命令替换

将命令的输出结果赋值给变量:

current_date=$(date)
echo "当前时间是:$current_date"

也可以使用反引号实现相同功能:

current_date=`date`

3.3 输入输出操作

读取用户输入:

read -p "请输入你的名字:" username
echo "你好,$username"

输出重定向:

echo "Hello" > output.txt     # 覆盖写入
echo "World" >> output.txt    # 追加写入

四、条件判断与控制结构

4.1 if 语句

age=20
if [ $age -ge 18 ]; thenecho "你已成年"
elseecho "你还未成年"
fi

4.2 比较运算符

运算符含义
-eq等于
-ne不等于
-lt小于
-le小于等于
-gt大于
-ge大于等于

4.3 字符串比较

str1="hello"
str2="world"
if [ "$str1" = "$str2" ]; thenecho "字符串相等"
elseecho "字符串不相等"
fi

4.4 case 语句

case $1 instart)echo "启动服务";;stop)echo "停止服务";;*)echo "未知命令";;
esac

五、循环结构

5.1 for 循环

for i in {1..5}; doecho "第 $i 次循环"
done

遍历数组:

names=("Alice" "Bob" "Charlie")
for name in "${names[@]}"; doecho "Hello, $name"
done

5.2 while 循环

count=1
while [ $count -le 5 ]; doecho "计数:$count"count=$((count + 1))
done

5.3 until 循环(直到条件为真)

count=1
until [ $count -gt 5 ]; doecho "计数:$count"count=$((count + 1))
done

六、函数与模块化编程

6.1 定义函数

greet() {echo "你好,$1"
}greet "Alice"
greet "Bob"

6.2 返回值与局部变量

add() {local result=$(( $1 + $2 ))echo $result
}sum=$(add 3 5)
echo "3 + 5 = $sum"

6.3 函数参数传递

函数参数通过 $1, $2, ... 传递:

log() {echo "[$(date +%H:%M:%S)] $1"
}log "脚本开始执行"

七、数组与集合操作

7.1 定义数组

fruits=("apple" "banana" "cherry")

7.2 访问数组元素

echo "第一个水果是:${fruits[0]}"
echo "所有水果是:${fruits[@]}"

7.3 遍历数组

for fruit in "${fruits[@]}"; doecho "$fruit"
done

7.4 数组操作

  • 添加元素:
fruits+=("orange")
  • 删除元素:
unset fruits[1]
  • 获取数组长度:
echo "水果数量:${#fruits[@]}"

八、脚本参数与退出状态

8.1 获取脚本参数

echo "脚本名称:$0"
echo "第一个参数:$1"
echo "所有参数:$@"
echo "参数个数:$#"

8.2 退出状态码

脚本的退出状态码用于表示执行是否成功:

exit 0   # 成功
exit 1   # 错误

可以通过 $? 获取上一个命令的退出状态:

ls /nonexistent
echo "上一个命令的状态码:$?"

九、文件与目录操作

9.1 文件测试

if [ -f "file.txt" ]; thenecho "文件存在"
fi

常见测试操作符:

操作符含义
-f是否为文件
-d是否为目录
-r是否可读
-w是否可写
-x是否可执行

9.2 文件操作示例

  • 创建文件:
touch newfile.txt
  • 删除文件:
rm -f file.txt
  • 移动/重命名文件:
mv oldname.txt newname.txt
  • 查看文件内容:
cat file.txt

十、调试与优化脚本

10.1 调试脚本

使用 -x 参数调试脚本:

bash -x script.sh

或者在脚本开头加上:

set -x

关闭调试:

set +x

10.2 脚本优化技巧

  • 使用 set -u 防止使用未定义变量。
  • 使用 set -e 在出现错误时立即退出脚本。
  • 使用 trap 捕获信号,进行清理操作:
trap "echo '脚本被中断'; exit 1" INT
  • 使用 getopts 解析命令行参数:
while getopts "a:b:c" opt; docase $opt ina)echo "选项 a 的值:$OPTARG";;b)echo "选项 b 的值:$OPTARG";;c)echo "选项 c 被设置";;\?)echo "无效选项:-$OPTARG";;esac
done

十一、实战项目:自动化备份脚本

#!/bin/bash# 设置变量
backup_dir="/backup"
source_dir="/home/user/documents"
timestamp=$(date +%Y%m%d%H%M%S)
backup_file="$backup_dir/backup_$timestamp.tar.gz"# 创建备份目录(如果不存在)
mkdir -p $backup_dir# 执行备份
tar -czf $backup_file $source_dir# 检查是否成功
if [ $? -eq 0 ]; thenecho "备份完成:$backup_file"
elseecho "备份失败"exit 1
fi

十二、高级主题与最佳实践

12.1 使用正则表达式

if [[ "hello123" =~ ^[a-zA-Z0-9]+$ ]]; thenecho "匹配成功"
fi

12.2 使用关联数组(Bash 4+)

declare -A user_info
user_info["name"]="Alice"
user_info["age"]=25
echo "用户姓名:${user_info[name]}"

12.3 使用子 Shell

(cd /tmptouch testfile
)

12.4 使用 Here Document

cat << EOF > output.txt
这是第一行
这是第二行
EOF

12.5 使用别名与函数库

可以将常用函数放入一个 .sh 文件中作为库文件:

# utils.sh
log() {echo "[$(date +%H:%M:%S)] $1"
}

在主脚本中引用:

source utils.sh
log "脚本开始执行"

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/89875.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/89875.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DelayQueue延迟队列的使用

1、DelayQueue简介 DelayQueue 也是 Java 并发包&#xff08;java.util.concurrent&#xff09;中的一个特殊队列,用于在指定的延迟时间之后处理元素。 DelayQueue的一些关键特性&#xff1a; 延迟元素处理&#xff1a;只有当元素的延迟时间到期时&#xff0c;元素才能被取出…

QT6 源,七章对话框与多窗体(6) 颜色对话框 QColorDialog :本类的属性,信号函数,静态成员函数,以及源代码

&#xff08;1&#xff09;本类的继承关系如下 &#xff1a;&#xff08;2&#xff09; 对于本标准颜色对话框来讲&#xff0c;学会使用其静态函数以获取到颜色就足够了。&#xff08;3&#xff09; 开始学习本类的静态成员函数 &#xff1a;&#xff08;4&#xff09;测试一下…

金仓数据库:融合进化,智领未来——2025年数据库技术革命的深度解析

引言 在数字中国战略的推动下&#xff0c;数据库作为数字经济的基础设施&#xff0c;正经历着前所未有的技术重构。2025年7月15日&#xff0c;电科金仓以"融合进化&#xff0c;智领未来"为主题&#xff0c;发布了新一代数据库产品矩阵&#xff0c;标志着国产数据库在…

【人工智能99问】卷积神经网络(CNN)的结构和原理是什么?(10/99)

文章目录卷积神经网络&#xff08;CNN&#xff09;的结构及原理一、CNN的核心结构1. 输入层&#xff08;Input Layer&#xff09;2. 卷积层&#xff08;Convolutional Layer&#xff09;2. 卷积层的核心机制&#xff1a;局部感受野与权值共享3. 池化层&#xff08;Pooling Laye…

CCF编程能力等级认证GESP—C++7级—20250628

CCF编程能力等级认证GESP—C7级—20250628单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09;判断题&#xff08;每题 2 分&#xff0c;共 20 分&#xff09;编程题 (每题 25 分&#xff0c;共 50 分)线图调味平衡单选题&#xff08;每题 2 分&#xff0c;共 30 分&…

《Python 类设计模式:属性分类(类属性 VS 实例属性)与方法类型(实例 / 类 / 静态)详解》

Python 类和对象&#xff1a;从 "图纸" 到 "实物" 的编程思维面向对象编程&#xff08;Object-Oriented Programming&#xff0c;简称OOP &#xff09;是一种通过组织对象来编程的方法。1.初识类和对象&#xff1a;用生活例子看透核心概念1.1类-class物与类…

Eureka服务端启动

目录 1、相关文章 2、创建eureka-server子工程 3、父工程build.gradle引入版本依赖管理 4、子工程build.gradle引入依赖 5、将main重命名为EurekaApplication并修改代码 6、添加application.yml文件 7、启动工程并访问 8、访问界面如下 9、 完整目录结构 1、相关文章 …

AWS Partner: Sales Accreditation (Business)

AWS Partner: Sales Accreditation &#xff08;Business&#xff09;云概念和AWS云计算什么是云计算&#xff1f;计算的演变趋势云计算部署模型AWS 客户采用的模式为什么客户选择AWSAWS竞争优势高可用的全球基础设施AWS服务服务广度和深度AWS产品和服务服务类别AWS解决方案库A…

深入理解设计模式之中介者模式:解耦对象交互的利器

为什么需要中介者&#xff1f;在软件开发中&#xff0c;我们经常会遇到对象之间需要相互通信的场景。当系统规模较小时&#xff0c;对象直接相互引用并通信可能不会带来太大问题。但随着系统复杂度增加&#xff0c;对象间的交互关系会变得错综复杂&#xff0c;形成一个复杂的网…

从 0 安装 Label Studio:搭建可后台运行的数据标注平台(systemd 实践

本文将介绍如何使用 pip 安装 Label Studio&#xff0c;并通过 systemd 实现开机自启与后台运行&#xff0c;适用搭建个人项目的数据标注平台。 一、Label Studio 简介 Label Studio 是一个开源、跨模态的数据标注工具&#xff0c;支持文本、图像、音频、视频、HTML等多种类型…

【数据结构】链表(linked list)

目录 一、链表的介绍 二、单链表 1. 单链表的初始化 2. 单链表的插入 &#xff08;1&#xff09;动态申请一个节点 &#xff08;2&#xff09;头插法 &#xff08;3&#xff09;尾插法 &#xff08;4&#xff09;按照位置来插入 &#xff08;5&#xff09;在地址之前插…

反序列化漏洞1-PHP序列化基础概念(0基础超详细)

一.PHP序列化基础概念首先当我们看到反序列化漏洞这个概念&#xff0c;我们的第一个问题是什么是反序列化&#xff1f;那么我们要知道什么是反序列化就要知道什么是序列化。序列化就是可以将一个对象压缩并格式化成字符串&#xff0c;可以将该对象保存下来&#xff0c;以便存储…

【微服务】Ocelot微服务网关

目录 一、目的 二、Ocelot介绍 三、.Net中使用Ocelot搭建网关服务 3.1 搭建网关Ocelot步骤 3.1.1、创建Net7 WebApi服务 3.1.2、Nuget引入-Ocelot程序包&#xff08;版本&#xff1a;19.0.2&#xff09; 3.1.3、配置中间件和IOC注册 3.1.4 配置文件编辑Ocelot网关配置信…

零基础入门:用按键精灵实现视频自动操作(附完整脚本)

摘要&#xff1a;本文手把手教你编写视频平台的自动化脚本&#xff0c;涵盖点击、循环、防检测等核心技巧&#xff0c;无需编程基础&#xff0c;轻松实现自动播放/点赞/跳过广告。&#xff08;使用按键精灵2024版演示&#xff09; 一、应用场景 自动化操作&#xff1a;自动跳过…

AI(学习笔记第六课) 使用langchain进行AI开发 load documents(csv和文件夹)

文章目录AI(学习笔记第六课) 使用langchain进行AI开发 load documents(csv和文件夹)学习内容&#xff1a;1.load documents&#xff08;csv&#xff09;1.1 学习url1.2 load csv文件1.2.1 默认load1.2.2 csv文件内容1.2.2 执行csv文件的load1.3 Customizing the CSV parsing an…

企业运维实战:Jenkins 依赖 JDK21 与应用需 JDK1.8 共存方案(含流水线配置)

前言&#xff1a;在企业运维中&#xff0c;“工具升级”与“业务兼容”的平衡始终是核心挑战。近期我们遇到一个典型场景&#xff1a;Jenkins 升级到 2.450 版本后&#xff0c;强制要求 JDK21 运行环境&#xff1b;但开发团队的应用程序因框架依赖&#xff0c;必须使用 JDK1.8 …

爬虫小知识三:selenium库

前言 selenium 库是一种用于 Web 应用程序测试的工具&#xff0c;它可以驱动浏览器执行特定操作&#xff0c;自动按照脚本代码做出单击、输入、打开、验证等操作&#xff0c;支持的浏览器包括 IE、Firefox、Safari、Chrome、Opera 等。 与 requests 库不同的是&#xff0c;se…

Jmeter使用 -1

1 接口测试1.1 为什么要进行接口测试接口测试能够绕过前端校验&#xff0c;对后端的接口处理逻辑进行测试&#xff08;数据的边界/格式/类型&#xff09;在一些需要重复测试的需求中&#xff0c;接口自动化的效率比手工执行效率高1.2 接口测试流程熟悉API接口文档&#xff08;接…

GitHub 趋势日报 (2025年07月16日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图2415markitdown570claude-code434ART330erpnext150MusicFree146rustdesk129vanna80…

Python+Tkinter制作音频格式转换器

我们将使用Python的Tkinter库来构建一个音频格式转换器界面。由于音频转换需要实际的处理&#xff0c;我们将使用pydub库&#xff08;需要安装&#xff09;来进行音频格式转换。同时&#xff0c;我们会使用ffmpeg作为后端&#xff0c;因此请确保系统中已安装ffmpeg并添加到环境…