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

从零开始学Shell编程:从基础到实战案例

从零开始学Shell编程:从基础到实战案例

文章目录

  • 从零开始学Shell编程:从基础到实战案例
    • 一、认识Shell:是什么与为什么学
      • 1.1 Shell的定义
      • 1.2 常用Shell解释器
    • 二、Shell编程快速入门:编写第一个脚本
      • 2.1 步骤1:创建脚本文件
      • 2.2 步骤2:赋予执行权限
      • 2.3 步骤3:执行脚本
    • 三、Shell核心语法:变量与字符串
      • 3.1 变量:定义、使用与修改
        • 3.1.1 变量定义规则
        • 3.1.2 变量使用
        • 3.1.3 变量修改与删除
      • 3.2 字符串:单引号、双引号与常用操作
        • 3.2.1 三种字符串定义方式对比
        • 3.2.2 字符串常用操作
    • 四、流程控制:让脚本“有判断、会循环”
      • 4.1 条件判断:if...else语句
        • 4.1.1 语法格式
        • 4.1.2 条件表达式
        • 4.1.3 示例:成绩评级
      • 4.2 循环执行:for与while语句
        • 4.2.1 for循环:已知循环范围
        • 4.2.2 while循环:按条件结束
    • 五、实战案例:完整猜数字游戏
      • 5.1 代码实现

在Linux系统操作中,Shell编程是提升效率的重要技能。它不仅能帮助我们自动化重复任务,还能整合各类命令实现复杂功能。本文将从Shell的基础概念讲起,逐步深入变量、字符串、运算符、流程控制、函数、数组等核心知识点,最后通过实战案例巩固所学,带你快速入门Shell编程。

一、认识Shell:是什么与为什么学

1.1 Shell的定义

Shell是用C语言编写的程序,它充当用户与操作系统内核之间的“桥梁”——用户通过Shell可以访问操作系统内核的服务。从功能上看,它类似Windows系统下的commandcmd.exe,但功能更强大、灵活性更高。

同时,Shell具有双重身份:

  • 命令语言:可以直接在终端输入命令,执行文件操作、进程管理等任务;
  • 程序设计语言:支持变量、函数、流程控制等编程特性,能编写脚本(Shell Script)实现自动化操作。

需要注意的是,“Shell编程”通常指编写Shell脚本,而非开发Shell解释器本身。

1.2 常用Shell解释器

Shell解释器是执行Shell脚本的核心工具,Linux系统中支持多种解释器,通过cat /etc/shells命令可查看系统已安装的解释器。其中:
在这里插入图片描述

  • /bin/sh:早期的Bourne Shell,功能较基础;
  • /bin/bash:Bourne Again Shell,兼容sh且新增了大量特性(如命令补全、历史记录),是目前大多数Linux系统(如CentOS、Ubuntu)的默认Shell,也是本文的主要使用解释器;
  • /sbin/nologin:非交互Shell,通常用于禁止用户登录。

二、Shell编程快速入门:编写第一个脚本

学习Shell编程无需复杂的开发环境,只需一个文本编辑器(如vi/vim)和Shell解释器即可。下面以“打印Hello World”为例,带你完成第一个Shell脚本的编写与执行。

2.1 步骤1:创建脚本文件

使用vi编辑器在指定目录(如/root/shelldemo)创建脚本文件hello.sh.sh是Shell脚本的约定后缀,不影响执行):

# 1. 创建存放脚本的目录(若不存在)
mkdir -p /root/shelldemo
# 2. 进入目录
cd /root/shelldemo
# 3. 用vi创建并编辑hello.sh
vi hello.sh

在这里插入图片描述
在这里插入图片描述
vi编辑器中输入以下内容:

#!/bin/bash
# 这是注释,打印Hello World
echo "Hello World!"
  • #!/bin/bash约定标记,告诉系统该脚本使用/bin/bash解释器执行;
  • #:注释符号,后面的内容不会被执行;
  • echo:输出命令,用于向终端打印文本。

输入完成后,按Esc键,输入:wq保存并退出vi

2.2 步骤2:赋予执行权限

刚创建的脚本文件默认只有“读”和“写”权限,需要通过chmod命令赋予“执行权限”:

# 给当前用户添加执行权限(+x表示新增执行权限,./hello.sh指定脚本路径)
chmod +x ./hello.sh

在这里插入图片描述

通过ls -l查看权限是否生效,若输出中包含-rwxr-xr-x,说明已成功添加执行权限:

ls -l hello.sh
# 输出示例:-rwxr-xr-x 1 root root 32 May 20 05:35 hello.sh

2.3 步骤3:执行脚本

Shell脚本有3种常见执行方式,可根据场景选择:

执行方式命令示例说明
相对路径执行./hello.sh.表示“当前目录”,系统会直接在当前目录寻找脚本并执行(需提前赋予执行权限)
绝对路径执行/root/shelldemo/hello.sh直接指定脚本的完整路径,无需进入脚本所在目录(需执行权限)
解释器参数执行sh hello.sh直接调用sh解释器,将脚本作为参数传入(无需执行权限

执行结果如下:

# 相对路径执行
./hello.sh
# 输出:Hello World!# 解释器参数执行(即使无执行权限也能运行)
sh hello.sh
# 输出:Hello World!

在这里插入图片描述

注意:若直接输入hello.sh执行,系统会在PATH环境变量指定的目录中寻找脚本,若当前目录不在PATH中,会提示“command not found”,因此需用./hello.sh明确“当前目录”。
在这里插入图片描述

三、Shell核心语法:变量与字符串

变量和字符串是Shell编程的基础,掌握它们能帮你存储和处理数据。

3.1 变量:定义、使用与修改

Shell变量无需声明数据类型,直接通过“变量名=值”的格式定义,且等号两边不能有空格

3.1.1 变量定义规则
  • 变量名首字符必须是字母(a-z/A-Z);
  • 变量名中间可包含下划线(_),但不能有空格或标点符号;
  • 不能使用Shell关键字(如iffor,可通过help命令查看关键字)。

示例:

# 正确定义:变量名见名知意,多单词用下划线分隔
your_name="bigdata.com"
student_age=20# 错误定义:等号两边有空格、包含特殊字符
# your_name = "bigdata.com" (错误:等号有空格)
# student-age=20 (错误:包含减号)

在这里插入图片描述

3.1.2 变量使用

使用变量时,在变量名前加$符号,若需明确变量边界,可加{}(推荐):

your_name="bigdata.com"
# 两种使用方式,输出结果相同
echo $your_name
echo ${your_name}# 明确变量边界的场景:拼接字符串
echo "Hello, ${your_name}_user"  # 输出:Hello, bigdata.com_user
# 若不加{}:echo "Hello, $your_name_user" 会被解析为“变量your_name_user”,导致错误

在这里插入图片描述

3.1.3 变量修改与删除
  • 修改变量:直接重新赋值即可(普通变量支持修改);
  • 只读变量:用readonly关键字定义,赋值后无法修改或删除;
  • 删除变量:用unset命令删除普通变量(无法删除只读变量)。

示例:

# 1. 修改普通变量
name="hadoop"
echo $name  # 输出:hadoop
name="spark"
echo $name  # 输出:spark# 2. 定义只读变量
readonly readonly_name="linux"
# readonly_name="ubuntu"  # 错误:只读变量无法修改,执行会提示“readonly variable”# 3. 删除普通变量
unset name
echo $name  # 输出为空(变量已删除)# unset readonly_name  # 错误:无法删除只读变量

在这里插入图片描述

3.2 字符串:单引号、双引号与常用操作

字符串是Shell中最常用的数据类型,支持单引号、双引号和无引号三种定义方式,功能差异主要体现在“变量解析”和“转义字符”上。

3.2.1 三种字符串定义方式对比
定义方式示例特点
单引号str='I love $your_name'1. 原样输出所有字符,不解析变量($your_name不会被替换为实际值);
2. 不能包含单独的单引号(即使转义也不行)
双引号str="I love $your_name"1. 解析变量($your_name会被替换为实际值);
2. 支持转义字符(如\n换行、\"双引号)
无引号str=I love bigdata1. 解析变量,但不支持转义字符;
2. 字符串中不能有空格(否则会被视为多个参数)

示例:

your_name="bigdata"
# 单引号:不解析变量
str1='I love $your_name'
echo $str1  # 输出:I love $your_name# 双引号:解析变量
str2="I love $your_name"
echo $str2  # 输出:I love bigdata# 双引号:支持转义字符
str3="Hello\nWorld"
echo -e $str3  # 输出:Hello(换行)World(-e启用转义)

在这里插入图片描述

3.2.2 字符串常用操作

Shell提供了便捷的字符串处理方法,如获取长度、提取子串、查找子串位置。

操作语法示例结果
获取长度${#字符串}skill="hadoop"
echo ${#skill}
6(hadoop共6个字符)
提取子串${字符串:起始索引:长度}str="I am good at hadoop"
echo ${str:2:2}(从索引2开始,取2个字符)
am(索引从0开始,空格算1个字符)
查找子串位置expr index "$字符串" 子串str="I am good at hadoop"
echo \expr index “$str” am``(反引号包裹命令)
3(am从第3个字符开始,位置从1算)

注意expr index命令返回的是“子串中任意字符首次出现的位置”,而非完整子串的位置,若需精确查找完整子串,需结合其他命令(如grep)。

四、流程控制:让脚本“有判断、会循环”

默认情况下,Shell脚本按“从上到下”顺序执行。通过流程控制语句,可实现“条件判断”和“循环执行”,让脚本更灵活。

4.1 条件判断:if…else语句

if...else语句根据条件的“成立与否”(true/false)执行不同代码块,支持“单支”“双支”“多支”三种场景。

4.1.1 语法格式
  • 单支:仅当条件成立时执行代码
    if [ 条件 ]; then命令1  # 条件成立时执行
    fi  # 结束if语句(必须)
    
  • 双支:条件成立/不成立分别执行不同代码
    if [ 条件 ]; then命令1  # 条件成立
    else命令2  # 条件不成立
    fi
    

在这里插入图片描述

  • 多支:多个条件依次判断,满足一个即执行
    if [ 条件1 ]; then命令1
    elif [ 条件2 ]; then命令2
    ...
    else命令n  # 所有条件不成立时执行
    fi
    

在这里插入图片描述

4.1.2 条件表达式

条件判断依赖“条件表达式”,常见类型包括:

  • 数字比较:用-eq(等于)、-gt(大于)、-lt(小于)等运算符(仅支持整数);
  • 字符串比较:用=(等于)、!=(不等于)、-z(空字符串)、-n(非空字符串);
  • 文件判断:用-f(普通文件)、-d(目录)、-e(文件存在)等。
4.1.3 示例:成绩评级

根据输入的成绩(0-100)输出评级(优秀/良好/及格/不及格):

# 创建脚本grade.sh
vi grade.sh

输入内容:

#!/bin/bash
score=$1  # $1表示执行脚本时传入的第一个参数
if [ $score -ge 90 ]; thenecho "优秀"
elif [ $score -ge 80 ]; thenecho "良好"
elif [ $score -ge 60 ]; thenecho "及格"
elseecho "不及格"
fi

执行脚本并传入参数(如“85”):

chmod +x grade.sh
./grade.sh 85  # 输出:良好
./grade.sh 59  # 输出:不及格

在这里插入图片描述
在这里插入图片描述

4.2 循环执行:for与while语句

循环用于“重复执行某段代码”,Shell中常用forwhile循环,分别适用于“已知循环次数”和“未知循环次数(按条件结束)”的场景。

4.2.1 for循环:已知循环范围

for循环有两种常用格式:

格式适用场景示例(打印1-5)
数值循环已知起始值、结束值、步长for ((i=1; i<=5; i++)); do echo $i; done
列表循环遍历已知列表(如数组、文件列表)for i in 1 2 3 4 5; do echo $i; done

示例1:计算1-10的累加和

vi sum_for.sh

输入内容:

#!/bin/bash
sum=0  # 存储累加结果
# 数值循环:i从1到10,每次+1
for ((i=1; i<=10; i++)); dosum=$((sum + i))  # $((...))用于算术运算
done
echo "1-10的累加和:$sum"  # 输出:55

示例2:遍历目录下的文件
打印/root/shelldemo目录下的所有文件名:

vi list_files.sh

输入内容:

#!/bin/bash
# 列表循环:遍历ls命令的结果(即目录下的文件)
for filename in $(ls /root/shelldemo); doecho "文件名:$filename"
done
4.2.2 while循环:按条件结束

while循环通过“条件是否成立”控制循环,适用于“未知循环次数”的场景(如等待用户输入正确值)。

语法格式

while [ 条件 ]; do命令1修改条件  # 避免死循环
done

示例:猜数字游戏(简化版)
程序内置1-10的随机数,用户猜数字,直到猜对为止:

vi guess_simple.sh

输入内容:

#!/bin/bash
# 生成1-10的随机数(RANDOM是系统变量,0-32767)
num=$[RANDOM%10+1]
while true; do  # true表示无限循环,需在内部用exit退出read -p "猜一个1-10的数字:" caiif [ $cai -eq $num ]; thenecho "恭喜猜对了!"exit  # 猜对后退出循环elif [ $cai -gt $num ]; thenecho "猜大了,再试试!"elseecho "猜小了,再试试!"fi
done

执行脚本,体验交互过程:

chmod +x guess_simple.sh
./guess_simple.sh
# 输出示例:
# 猜一个1-10的数字:5
# 猜小了,再试试!
# 猜一个1-10的数字:8
# 恭喜猜对了!

五、实战案例:完整猜数字游戏

结合前面所学的变量、流程控制、随机数生成等知识,我们来实现一个“1-100的猜数字游戏”,规则如下:

  1. 程序随机生成1-100的整数;
  2. 用户每次输入一个数字,系统提示“大了”“小了”或“猜对了”;
  3. 猜对后提示“游戏结束”,并退出程序。

5.1 代码实现

创建脚本guess_number.sh

vi guess_number.sh

输入内容:

#!/bin/bash
# 猜数字游戏:1-100的随机数,直到猜对为止# 1. 生成1-100的随机数(RANDOM%100得到0-99,+1后为1-100)
target_num=$[RANDOM%100+1]# 2. 无限循环,等待用户输入
while true; do# 接收用户输入(-p提示用户输入内容)read -p "计算机生成了1-100的随机数,请猜:" user_guess# 3. 判断输入是否为整数(避免非数字输入导致脚本报错)if ! [[ $user_guess =~ ^[0-9]+$ ]]; thenecho "请输入有效的整数
http://www.dtcms.com/a/357838.html

相关文章:

  • 再来,一次内存溢出
  • 【人工智能99问】参数调整技术(31/99)
  • 【Spring Cloud Alibaba】前置知识(一)
  • RAG教程6:cohere rerank重排
  • 物理AI:连接数字智能与物理世界的下一代人工智能范式
  • 函数的逆与原象
  • 【完整源码+数据集+部署教程】传送带建筑材料识别系统源码和数据集:改进yolo11-AFPN-P345
  • vue3 表单项不对齐的解决方案
  • gpu与cpu各厂商的优劣
  • 【系列01】端侧AI:构建与部署高效的本地化AI模型
  • 【编号513】2025年全国地铁矢量数据
  • PCIe 6.0的速度奥秘:数学视角下的编码革命与信号完整性突破
  • 永磁同步电机无速度算法--传统脉振方波注入法(2)
  • Linux系统编程—进程概念
  • 疯狂星期四文案网第54天运营日记
  • 动态规划--Day03--打家劫舍--198. 打家劫舍,213. 打家劫舍 II,2320. 统计放置房子的方式数
  • Android系统框架知识系列(十九):Android安全架构深度剖析 - 从内核到应用的全栈防护
  • 深入解析Paimon MergeFunction
  • 图解帕累托前沿(pareto frontier)
  • 嵌入式Linux驱动开发:i.MX6ULL按键中断驱动(非阻塞IO)
  • stm32单片机使用tb6612驱动编码器电机并测速的驱动代码详解—详细参考开发手册(可移植+开发手册)
  • 文本嵌入模型的本质
  • 《ArkUI 记账本开发:状态管理与数据持久化实现》
  • 分布式锁在支付关闭订单场景下的思考
  • Product Hunt 每日热榜 | 2025-08-29
  • 逻辑漏洞 跨站脚本漏洞(xss)
  • 早期人类奴役AI实录:用Comate Zulu 10min做一款Chrome插件
  • nacos登录认证
  • 【算法】15. 三数之和
  • 学习做动画7.跳跃