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

Shell脚本(2)

文章目录

  • Shell变量及赋值:从基础到实战的全面指南
    • 一、Shell变量的本质与核心类型
    • 二、自定义变量:从定义到使用的完整流程
      • 1. 基础定义:赋值语法与规则
        • 正确与错误示例对比
      • 2. 变量的引用:`$`与`${}`的用法
        • 示例1:基础引用(无歧义场景)
        • 示例2:`${}`的必要性(有歧义场景)
      • 3. 变量的查看与删除
    • 三、赋值的“花样操作”:引号、命令替换与交互
      • 1. 引号的区别:双引号`"`、单引号`'`、反撇号`` ` ``
        • 实战示例:三种引号的效果对比
      • 2. 交互式赋值:`read`命令获取用户输入
        • 实战示例1:基础交互(输入姓名)
        • 实战示例2:隐藏输入(输入密码)
        • 实战示例3:从文件读取内容赋值
    • 四、变量的作用范围:局部与全局的切换
      • 1. 局部变量的局限性
      • 2. `export`:导出全局变量
        • 实战示例:导出全局变量
        • 查看与取消全局变量
    • 五、特殊变量:只读变量与预定义变量
      • 1. 只读变量:`readonly`,定义后不可修改
      • 2. 预定义变量:Shell内置的“工具变量”
        • 实战示例:预定义变量的用法
    • 六、总结:Shell变量的核心要点

Shell变量及赋值:从基础到实战的全面指南

在Shell脚本编程中,变量是承载临时数据的核心载体,也是实现脚本灵活性和可维护性的基础。无论是简单的命令行操作,还是复杂的自动化脚本,掌握变量的定义、赋值与使用逻辑,都是提升效率的关键。本文将从变量的本质出发,详细讲解Shell中变量的类型、赋值方式、作用范围及实战技巧,帮你彻底搞懂Shell变量的“前世今生”。

一、Shell变量的本质与核心类型

变量的核心作用是“临时存储可变化的数据”,避免重复编写固定内容——比如脚本中多次用到的路径、版本号、用户输入等,用变量替代后,修改时只需改一处即可。

Shell中的变量无需提前声明类型(弱类型语言),直接赋值即可使用。根据作用场景,常见变量可分为5类:

变量类型作用说明典型示例
自定义变量用户手动定义,仅在当前Shell环境生效(局部变量)name="Linux"version=2.0
环境变量全局生效,可在所有子Shell中使用,常用于配置系统环境(如路径、语言)PATHHOMELANG
只读变量定义后不可修改或删除,避免误操作导致数据丢失readonly PI=3.14
位置变量接收脚本执行时传入的参数,按顺序对应($1代表第1个参数,$2代表第2个)./script.sh arg1 arg2中,$1=arg1
预定义变量Shell内置的“开箱即用”变量,用于获取脚本执行状态、参数数量等$?(上条命令状态码)、$#(参数总数)

二、自定义变量:从定义到使用的完整流程

自定义变量是日常使用最频繁的类型,核心语法简单,但细节(如符号、空格)直接影响正确性。

1. 基础定义:赋值语法与规则

自定义变量的赋值格式严格遵循 变量名=变量值,且有3个关键规则:

  • 等号=前后不能有空格(否则Shell会把变量名当命令执行);
  • 变量名必须以字母或下划线开头,不能包含特殊字符(如+-*$等);
  • 变量值若包含空格或特殊符号,需用双引号"或单引号'包裹(下文详解引号区别)。
正确与错误示例对比
# 正确:等号无空格,变量名合规
product="Shell教程"
version=1.0
install_path="/usr/local/shell"# 错误1:等号有空格(Shell会把“name”当命令,“Linux”当参数)
name = "Linux"  # 报错:bash: name: 未找到命令...# 错误2:变量名以数字开头(不符合命名规则)
123version=2.0  # 报错:bash: 123version=2.0: 语法错误: 无效的算术运算符

在这里插入图片描述

2. 变量的引用:$${}的用法

引用变量时,需在变量名前加$符号;若变量名后紧跟其他字符(如字母、数字),需用${}包裹变量名,避免Shell误判变量范围。

示例1:基础引用(无歧义场景)
product="Python"
version=3.11
# 直接用$引用变量,拼接字符串
echo "当前版本:$product $version"  # 输出:当前版本:Python 3.11

在这里插入图片描述

示例2:${}的必要性(有歧义场景)

若想输出“Python3.11”(变量后直接跟数字),不写${}会报错:

# 错误:Shell会把$product3.11当作一个变量(未定义,输出空)
echo "$product3.11"  # 正确:用${}明确变量范围,仅引用$product
echo "${product}3.11"  # 输出:Python3.11

在这里插入图片描述

3. 变量的查看与删除

  • 查看变量值:用echo $变量名echo ${变量名}
  • 删除变量:用unset 变量名(删除后变量值为空,不可恢复)。
name="Tom"
echo $name  # 输出:Tom# 删除变量
unset name
echo $name  # 输出:(空值,变量已被删除)

在这里插入图片描述

三、赋值的“花样操作”:引号、命令替换与交互

除了“变量名=固定值”的基础赋值,Shell还支持更灵活的赋值方式,应对空格、特殊字符、命令结果、用户输入等场景。

1. 引号的区别:双引号"、单引号'、反撇号`

引号的核心作用是“界定字符串范围”,但不同引号对变量和特殊字符的处理逻辑完全不同,这是Shell变量的高频考点。

引号类型对变量的处理对特殊字符($、\、`)的处理适用场景
双引号"识别变量(会替换为变量值)识别部分转义(如\n\t变量值含空格,需保留变量引用
单引号'不识别变量(原样输出$变量名所有字符均为普通字符(无转义)变量值含特殊符号(如$、`),需原样输出
反撇号`-(不用于界定字符串)执行引号内的命令,返回结果赋值为“命令执行后的输出”
实战示例:三种引号的效果对比
# 先定义一个基础变量
test_var="Linux"# 1. 双引号:识别变量,保留空格
echo "变量值:$test_var,当前目录:$(pwd)"  # 输出:变量值:Linux,当前目录:/root# 2. 单引号:不识别变量,特殊字符原样输出
echo '变量值:$test_var,当前目录:$(pwd)'  # 输出:变量值:$test_var,当前目录:$(pwd)# 3. 反撇号:执行命令,赋值为结果(与$()等价)
current_time=`date +%H:%M:%S`  # 执行date命令,将时间赋值给变量
echo "当前时间:$current_time"  # 输出:当前时间:15:30:45

注意:反撇号`不支持嵌套命令(如`ls `which python`会报错),推荐用$()替代,嵌套更灵活:
rpm -qc $(rpm -qf $(which useradd))(先找useradd路径,再查对应rpm包的配置文件)

在这里插入图片描述

2. 交互式赋值:read命令获取用户输入

当脚本需要“让用户手动输入内容”时(如输入密码、姓名),用read命令实现交互。read支持多种选项,优化交互体验:

选项作用说明
-p "提示信息"显示提示文本,告知用户需要输入什么(无需额外用echo输出提示)
-s输入内容不回显(隐藏输入,常用于输入密码)
-n 字符数限制输入的字符长度(输入达到指定长度后自动结束,无需按回车)
-t 秒数超时时间(超过指定秒数未输入,自动退出,避免脚本卡住)
实战示例1:基础交互(输入姓名)
# 用-p显示提示,输入内容赋值给name变量
read -p "请输入你的姓名:" name
echo "你好,$name!"  # 输出:你好,张三!(假设输入张三)

在这里插入图片描述

实战示例2:隐藏输入(输入密码)
# -s隐藏输入,-p提示,输入后赋值给pass变量
read -s -p "请输入密码:" pass
echo -e "\n密码已接收(已隐藏)"  # -e识别\n换行,避免输出紧跟在输入后

在这里插入图片描述

实战示例3:从文件读取内容赋值

read还支持从文件读取内容(而非键盘输入),用<指定文件路径:

# 先创建一个文件,写入IP地址
echo "192.168.1.100" > ip.txt# 从ip.txt读取内容,赋值给ip变量
read -p "读取IP:" ip < ip.txt
echo "获取的IP:$ip"  # 输出:获取的IP:192.168.1.100

在这里插入图片描述

四、变量的作用范围:局部与全局的切换

默认情况下,自定义变量是“局部变量”——仅在当前Shell环境生效,进入子Shell(如执行bash命令打开新Shell)后,局部变量会失效。若需变量在所有子Shell中可用,需用export命令导出为“全局变量”。

1. 局部变量的局限性

# 在当前Shell定义局部变量
name="张三"
echo "当前Shell:$name"  # 输出:当前Shell:张三# 进入子Shell(新的Shell环境)
bash
echo "子Shell:$name"    # 输出:子Shell:(空值,局部变量失效)# 退出子Shell,回到原Shell
exit
echo "回到原Shell:$name"  # 输出:回到原Shell:张三(原变量仍在)

在这里插入图片描述

2. export:导出全局变量

export的作用是“将局部变量提升为全局变量”,支持两种用法:

  • 先定义变量,再导出:变量名=值; export 变量名
  • 定义时直接导出:export 变量名=值
实战示例:导出全局变量
# 方式1:先定义,再导出
version=2.0
export version  # 导出为全局变量

在这里插入图片描述

# 方式2:定义时直接导出
export author="李四"# 进入子Shell,验证全局变量
bash
echo "子Shell:version=$version, author=$author"  # 输出:子Shell:version=2.0, author=李四# 退出子Shell
exit

在这里插入图片描述

查看与取消全局变量
  • 查看全局变量:用env命令(列出所有环境变量),或echo $变量名
  • 取消全局变量:用export -n 变量名(将全局变量变回局部变量,子Shell中不再生效)。
# 取消version的全局属性
export -n version# 进入子Shell,验证
bash
echo "子Shell version:$version"  # 输出:子Shell version:(空值,已变回局部)
exit

在这里插入图片描述

五、特殊变量:只读变量与预定义变量

除了自定义变量,Shell还提供两种特殊变量:只读变量(防修改)和预定义变量(内置工具),解决特定场景需求。

1. 只读变量:readonly,定义后不可修改

readonly定义的变量,无法用unset删除,也不能重新赋值,适合存储固定不变的常量(如π值、配置路径)。

# 定义只读变量
readonly PI=3.14159
echo "π值:$PI"  # 输出:π值:3.14159# 尝试修改(报错)
PI=3.14  # 报错:bash: PI: 只读变量# 尝试删除(报错)
unset PI  # 报错:bash: unset: PI: 无法取消设定: 只读 variable

在这里插入图片描述

2. 预定义变量:Shell内置的“工具变量”

预定义变量是Shell自带的,无需手动定义,直接引用即可,常用于脚本调试、参数处理、状态判断。

预定义变量作用说明
$?上一条命令的执行状态码:0=成功,非0=失败(如1=语法错误,2=参数错误)
$#脚本执行时传入的参数总数(如./script.sh a b c,$#=3)
$*所有参数的集合(将所有参数视为一个整体,用空格分隔)
$@所有参数的集合(将每个参数视为独立个体,适合循环遍历)
$$当前Shell或脚本的进程ID(PID)
$!上一个后台运行命令的进程ID(PID)
实战示例:预定义变量的用法
# 1. $?:判断上条命令是否成功
ls /tmp  # 执行一个正确的命令
echo "ls命令状态码:$?"  # 输出:ls命令状态码:0(成功)ls /nonexistent  # 执行一个错误的命令(目录不存在)
echo "ls错误状态码:$?"  # 输出:ls错误状态码:2(失败)# 2. $#、$*、$@:处理脚本参数(假设脚本名为test.sh)
#!/bin/bash
echo "参数总数:$#"    # 输出参数个数
echo "所有参数(整体):$*"  # 输出所有参数
echo "所有参数(独立):$@"  # 输出所有参数# 执行脚本:./test.sh arg1 arg2 arg3
# 输出结果:
# 参数总数:3
# 所有参数(整体):arg1 arg2 arg3
# 所有参数(独立):arg1 arg2 arg3

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

六、总结:Shell变量的核心要点

  1. 赋值语法变量名=变量值,等号无空格,特殊值用引号包裹;
  2. 引号逻辑:双引号识别变量,单引号原样输出,反撇号/$()执行命令;
  3. 作用范围:局部变量仅当前Shell有效,export导出为全局变量;
  4. 特殊场景read实现交互,readonly定义常量,预定义变量简化脚本;
  5. 避坑提醒:变量引用加$,歧义场景用${}$?判断命令状态。

掌握这些内容后,无论是写简单的命令行脚本,还是复杂的自动化工具,都能灵活运用变量提升效率,避免重复劳动和语法错误。Shell变量看似基础,却是通往Shell编程进阶的“第一道门”——打好基础,后续的循环、条件、函数等内容都会更易理解。

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

相关文章:

  • 洛谷p1028数的计算 详解
  • 【智能体】零代码学习 Coze 智能体(1)
  • 人工智能基础概念
  • java通过redis简单实现分布式锁
  • 【MySQL数据库】存储引擎 学习记录
  • 深度学习进阶
  • B站 XMCVE Pwn入门课程学习笔记(8)
  • Mybatis中缓存机制的理解以及优缺点
  • 详解 外部负载均衡器 → Ingress Controller Pod 这个过程
  • LCEDA电气规则
  • HTTPS的底层是怎么做的,使得数据更安全
  • 【python】python进阶——with关键字
  • 一个格式化方法一个打印语句完成一个基本日历展示,完成完美『终端呈现』(迭代升级)(彩色·Python)
  • 刀客doc:Instagram会成为Meta广告业务的第二曲线吗?
  • 机器视觉学习-day05-ROI切割
  • 博创软件慧云台庙务管理系统产品优势分析
  • Java -- 文件基础知识--Java IO流原理--FileReader
  • Makefile的使用
  • 进程组 会话 作业控制 守护进程
  • LeetCode 100 -- Day7
  • JDK8升级到JDK17的注意事项
  • @RequiredArgsConstructor 和构造同时使用,注入会不会导致空指针
  • Dify 中的 Signal Killed 问题排查指南
  • 强化学习入门专栏目录
  • 2002-2020年全国投入产出表数据
  • 【C++八股文】操作系统篇
  • C语言 部分内存相关的库函数
  • 广东省省考备考(第八十九天8.28)——判断推理(听课后强化训练)
  • 事务的五大状态
  • QT LInux 开发中一些常用的方法