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

Shell 脚本基础教程

引言

本教程将基于您提供的主题结构,逐步介绍 Shell 脚本的核心概念。我会使用中文解释,并提供清晰的代码示例(基于 Bash Shell)。所有内容真实可靠,参考了标准 Shell 编程实践。代码示例使用 Markdown 代码块,数学表达式(如变量操作)按规范格式化。

1.1 简介

Shell 脚本是一种自动化任务脚本语言,常用于 Linux/Unix 系统管理。它通过命令行解释器执行,能简化重复操作,如文件处理或系统监控。Shell 脚本的优势包括易学性和高效性,适合初学者入门。

1.2 Shell 解释器

Shell 解释器是执行脚本的核心程序,常见的有 Bash(Bourne Again SHell)。它读取用户命令并调用系统内核执行。例如,Bash 是大多数 Linux 发行版的默认解释器。

  • 检查当前解释器
echo $SHELL  # 输出当前 Shell 路径,如 /bin/bash

2.1 编写 Shell 脚本

编写 Shell 脚本需创建文本文件,首行指定解释器(如 #!/bin/bash),后续添加命令。脚本文件通常以 .sh 结尾。

  • 示例脚本:创建一个简单脚本打印欢迎信息。
#!/bin/bash
# 这是一个注释:打印欢迎消息
echo "Hello, Shell World!"  # echo 命令输出文本

2.2 执行 Shell 脚本

执行脚本前需赋予可执行权限,然后通过路径或解释器直接运行。

  • 步骤
chmod +x script.sh  # 添加执行权限
./script.sh        # 运行脚本,输出:Hello, Shell World!

  • 或直接使用解释器:
bash script.sh     # 无需权限,直接执行

3. Shell 程序:变量

变量用于存储数据,是脚本的核心元素。Shell 变量无严格类型,但需遵循语法规则。

3.1 语法格式

变量定义使用 变量名=值 格式,等号两侧无空格。变量名以字母或下划线开头,区分大小写。

  • 示例
name="Alice"  # 定义字符串变量
age=30        # 定义数值变量

3.2 变量使用

引用变量需加 $ 符号,如 $变量名。变量可用于命令参数或计算。

  • 示例
echo "Name: $name, Age: $age"  # 输出:Name: Alice, Age: 30
sum=$((age + 5))               # 算术计算,结果存储到 sum
echo "Sum: $sum"               # 输出:Sum: 35

  • 在数学表达式中,计算如 $sum = age + 5$ 使用 $(( )) 语法。
3.3 变量类型

Shell 变量主要分两类:

  • 局部变量:仅在当前脚本生效,通过 变量名=值 定义。
  • 环境变量:全局生效,通过 export 变量名=值 定义,如 PATH
export MY_VAR="Global"  # 设置为环境变量
echo $MY_VAR            # 输出:Global

4. 字符串

字符串是 Shell 中常见的数据类型,支持多种操作。

4.1 单引号

单引号 ' ' 内字符原样输出,不解析变量或转义符。

  • 示例
str='Hello $name'  # $name 不被解析
echo $str          # 输出:Hello $name

4.2 双引号

双引号 " " 可解析变量和转义符(如 \n)。

  • 示例
str="Hello, $name!\nWelcome."  # 解析 $name 和 \n
echo -e $str                   # 输出带换行的文本

4.3 获取字符串长度

使用 ${#字符串} 获取长度,长度值 $n$ 为整数。

  • 示例
str="Shell"
len=${#str}        # 获取长度
echo "Length: $len" # 输出:Length: 5

  • 数学表示:长度 $n = \text{len}(str)$,其中 $\text{len}$ 是长度函数。
4.4 提取子字符串

语法 ${字符串:起始位置:长度},位置从 0 开始计数。

  • 示例
str="HelloWorld"
sub=${str:1:4}     # 从索引 1 开始提取 4 个字符
echo "Substring: $sub" # 输出:ello

  • 数学表示:子串 $s = \text{substr}(str, start, length)$。
4.5 查找子字符串

使用 expr index "$字符串" "子串" 查找子串首次出现的位置,位置索引从 1 开始。

  • 示例
str="BashScript"
pos=$(expr index "$str" "Sc")  # 查找 "Sc" 的位置
echo "Position: $pos"          # 输出:5(因为 'S' 在索引 5)

  • 数学表示:位置 $p = \text{index}(str, substr)$,其中 $\text{index}$ 返回索引值。

Shell 传递参数

在 Shell 脚本中,参数传递是处理用户输入的基础功能。通过命令行执行脚本时,可以传递多个参数,脚本内部使用特殊变量来访问这些参数。下面我将逐步解释参数传递机制和相关特殊变量,确保内容清晰可靠。

5.1 Shell 传递参数的基本方式

当执行 Shell 脚本时,参数通过命令行提供,格式为 ./脚本名 参数1 参数2 ... 参数n。例如,运行 ./demo04.sh apple banana cherry,其中:

  • ./demo04.sh 是脚本文件名。
  • apple 是第一个参数。
  • banana 是第二个参数。
  • cherry 是第三个参数。

脚本内部使用位置变量 $n 来访问这些参数,其中 n 是一个数字(从 1 开始)。例如:

  • $1 表示第一个参数。
  • $2 表示第二个参数。
  • 以此类推。
5.2 Shell 中的特殊变量

除了位置参数,Shell 还提供了一些特殊变量来处理参数集合、状态和进程信息。这些变量在脚本中自动可用,无需声明。以下是关键变量及其用途:

  • $*:将所有参数作为一个完整的字符串输出。例如,如果参数是 apple banana cherry$* 会输出 "apple banana cherry"(一个字符串)。
  • $@:将所有参数作为列表输出。每个参数被视为独立项,便于循环处理。例如,在 for 循环中,$@ 会迭代为 applebananacherry
  • $#:输出参数的个数。例如,如果传递了三个参数,$# 的值是 $3$。
  • $?:查看上一个命令的退出状态。值为 $0$ 表示成功(命令正确执行),非零值表示错误(如 $1$ 表示一般错误)。
  • $$:输出当前脚本运行的进程 ID(PID)。这是一个唯一数字,用于标识脚本实例。
  • $!:输出后台运行的最后一个进程的 PID。例如,如果启动一个后台进程,$! 会存储其 ID。

这些变量在脚本调试和逻辑控制中非常有用,确保参数处理高效可靠。

6. Shell 运算符

在 Shell 中,运算符用于执行各种计算,包括算术、关系、逻辑和字符串操作。Shell 本身不支持直接数学表达式,但可以通过内置工具如 exprlet 或算术扩展 $(( )) 来实现。运算符使用时需注意转义,因为某些字符(如 *)在 Shell 中有特殊含义(通配符)。以下是主要运算符类别:

算术运算符

用于数值计算,常见运算符包括:

  • 加: $+$
  • 减: $-$
  • 乘: $\times$(需转义为 \*,因为 * 是通配符)
  • 除: $\div$(使用 /
  • 取余: $%$

例如,计算 $10 \times 5$ 时,必须转义乘法符号为 \*,否则 Shell 会误解释为通配符。

关系运算符

用于比较数值,通常在 test[ ] 命令中使用:

  • 等于: -eq
  • 不等于: -ne
  • 小于: -lt
  • 大于: -gt
  • 小于等于: -le
  • 大于等于: -ge

例如,检查 $a$ 是否等于 $b$,使用 [ $a -eq $b ]

逻辑运算符

用于布尔逻辑操作:

  • 与: &&(AND)
  • 或: ||(OR)
  • 非: !(NOT)

例如,条件 [ $a -gt 0 ] && [ $b -lt 10 ] 表示 $a > 0$ 且 $b < 10$。

字符串运算符

用于字符串处理:

  • 相等: =
  • 不相等: !=
  • 字符串长度为零: -z
  • 字符串长度非零: -n

例如,检查字符串是否为空: [ -z "$str" ]

代码示例

以下 Shell 脚本演示了参数传递和运算符的使用。脚本保存为 demo.sh,运行方式如 ./demo.sh 10 5

#!/bin/bash# 1. 演示参数传递
echo "第一个参数: $1"
echo "第二个参数: $2"
echo "所有参数(字符串): $*"
echo "所有参数(列表): $@"
echo "参数个数: $#"
echo "上一个命令状态: $?"  # 通常为0,表示成功# 2. 演示算术运算(使用 expr 工具,需转义 *)
a=$1
b=$2
sum=$(expr $a + $b)
product=$(expr $a \* $b)  # 转义 * 为 \*
echo "和: $sum"
echo "积: $product"# 3. 演示关系运算
if [ $a -gt $b ]; thenecho "$a 大于 $b"
elseecho "$a 不大于 $b"
fi# 4. 演示进程 ID
echo "当前脚本 PID: $$"
# 启动一个后台进程
sleep 5 &
echo "后台进程 PID: $!"

解释说明:
  • 参数处理:脚本接受两个参数(如数字),通过 $1$2 访问。
  • 算术运算:使用 expr 工具计算和与积,注意乘法必须转义(\*)。
  • 关系运算:使用 [ ]-gt 比较参数大小。
  • 进程信息$$ 显示当前脚本 PID,$! 显示后台进程 PID。
  • 运行后,$? 会显示上一个命令的退出状态(成功时为 $0$)。

这个脚本覆盖了用户查询的所有点,确保真实可靠。测试时,确保脚本有执行权限(chmod +x demo.sh)。

http://www.xdnf.cn/news/1395649.html

相关文章:

  • java序列化
  • Android系统框架知识系列(十九):Android安全架构深度剖析 - 从内核到应用的全栈防护
  • python学习打卡day48
  • “白月光”焦点何晟铭现身宁夏中宁,助力非遗与三农发展
  • 拎包入住搭建 Browser Use Agent:基于PPIO Model API +Agent 沙箱的一体化构建
  • 变量声明方式
  • linux学习-数据库
  • 中科米堆CASAIM五金配件三维扫描测量尺寸形位公差
  • 嵌入式Linux驱动开发:i.MX6ULL平台设备驱动
  • 使用 Docker 部署 Squid 为 Kubernetes 中的 Nexus3 提供公网代理访问
  • linux 条件变量与生产消费者模型
  • 玳瑁的嵌入式日记D29-0829(进程间通信)
  • Python OpenCV图像处理与深度学习:Python OpenCV开发环境搭建与入门
  • 基于能量方法的纳维-斯托克斯方程高阶范数有界性理论推导-陈墨仙
  • STM32CubeMX + HAL 库:基于 I²C 通信的 AHT20 高精度温湿度测量实验
  • 【系列03】端侧AI:构建与部署高效的本地化AI模型 第2章:端侧AI硬件入门
  • 134-细粒度多尺度符号熵和鲸鱼优化算法的滚动轴承故障诊断技术MSVM
  • Redis搭建哨兵模式一主两从三哨兵
  • 线程安全及死锁问题
  • 【好题推荐】运算符的构造运用
  • 光伏发多少电才够用?匹配家庭用电需求
  • #医疗AI时代的生物医学Go编程:高性能计算与精准医疗的案例分析(五)
  • Linux内核进程管理子系统有什么第三十八回 —— 进程主结构详解(34)
  • JUC并发编程09 - 内存(01) - JMM/cache
  • 嵌入式Linux设备树驱动开发 - dtsof驱动
  • Unity DateTime 相关
  • 处理器(CPU/MPU)的双发射是什么?
  • 命令扩展与重定向
  • 可解释人工智能XAI
  • 【机器学习深度学习】Embedding 与 RAG:让 AI 更“聪明”的秘密