Shell脚本(1)
文章目录
- Shell脚本编程规范与变量:从基础到实战
- 一、前言:编程语言的分类与Shell定位
- 1. 编程语言的两大范式
- 2. 编程语言排名参考
- 二、Shell核心概念:什么是Shell?
- 1. Shell的定义
- 2. Shell的作用
- 3. 常见Shell解释器
- 三、Shell脚本基础:从构成到执行
- 1. Shell脚本的定义与作用
- 2. Shell脚本的构成
- 示例:第一个Shell脚本
- 3. Shell脚本的执行步骤
- 步骤1:创建脚本文件
- 步骤2:赋予执行权限
- 步骤3:执行脚本
- 四、Shell变量:定义与使用
- 1. 变量的命名规则
- 示例:合法与非法变量名
- 2. 变量的定义与赋值
- 基本语法
- 示例:定义不同类型的变量
- 3. 变量的使用
- 示例:变量的调用
- 4. 特殊变量:Shell内置变量
- 示例:使用特殊变量
- 五、重定向与管道:Shell的“数据流控制”
- 1. 标准输入/输出/错误
- 2. 重定向操作
- (1)输出重定向:> 与 >>
- 示例:输出重定向
- (2)错误重定向:2> 与 2>>
- 示例:错误重定向
- (3)混合重定向:&> 与 2>&1
- 示例:混合重定向
- (4)输入重定向:<
- 示例:输入重定向
- 3. 管道操作:|
- 语法:`命令1 | 命令2 | 命令3`
- 示例:管道的常见用法
- 六、总结与实践建议
- 1. 核心知识点回顾
- 2. 实践建议
Shell脚本编程规范与变量:从基础到实战
在Linux系统运维与自动化开发中,Shell脚本是不可或缺的工具。它能将复杂的命令序列、流程控制逻辑整合为可复用的程序,极大提升工作效率。本文将从Shell的核心概念出发,详细讲解脚本编程规范、变量使用及常见操作,帮助初学者快速入门Shell开发。
一、前言:编程语言的分类与Shell定位
在学习Shell前,我们先明确它在编程语言体系中的位置:
1. 编程语言的两大范式
类型 | 核心思想 | 适用场景 | 代表语言 |
---|---|---|---|
面向过程 | 按步骤拆解任务,指令为中心 | 问题规模小、流程清晰的场景 | C、Shell |
面向对象 | 抽象为“对象”,数据为中心 | 复杂系统、大规模开发 | Java、Python、Golang |
面向过程语言更适合自动化脚本、简单工具开发,比如批量执行命令、定时备份;而面向对象语言则用于构建大型应用(如电商系统、云平台)。
2. 编程语言排名参考
了解语言流行度有助于选择学习方向,可通过TIOBE指数实时查看(2024年数据中,Python、C、Java稳居前三,Shell虽未进入前十,但在Linux运维领域不可或缺)。
二、Shell核心概念:什么是Shell?
1. Shell的定义
Shell是命令解释器,介于操作系统内核与用户之间,负责:
- 接收用户输入的命令
- 将命令解释为内核可执行的二进制指令
- 接收内核执行结果,反馈到终端显示
简单来说,Shell就是“翻译官”——把人类能理解的命令,翻译成计算机能懂的语言。
2. Shell的作用
Linux系统中,Shell的核心作用是连接用户与内核:
- 交互式场景:用户输入
ls
、cd
等命令,Shell实时解释执行 - 非交互式场景:执行Shell脚本文件,自动完成一系列命令
3. 常见Shell解释器
不同Shell的语法和功能略有差异,可通过cat /etc/shells
查看系统支持的Shell类型:
/bin/bash
:CentOS/RHEL默认Shell,功能最完善,兼容性强/bin/sh
:bash
的软链接(部分系统已被bash
替代)/bin/tcsh
//bin/csh
:C语言风格Shell,较少使用/sbin/nologin
:禁止用户登录的“特殊Shell”
为什么
/etc/shells
要记录合法Shell?
系统服务(如SSH、FTP)会通过该文件判断用户是否有权限登录,只有在列表中的Shell才能用于用户登录。
三、Shell脚本基础:从构成到执行
1. Shell脚本的定义与作用
Shell脚本是包含命令、变量、流程控制的文本文件,无需编译,直接由Shell解释执行。它的核心价值是:
- 自动化重复操作(如批量添加用户、软件部署)
- 整合复杂命令(如日志分析、数据备份)
- 标准化操作流程(避免人工操作失误)
2. Shell脚本的构成
一个规范的Shell脚本包含三部分:
- 解释器声明:第一行
#!/bin/bash
,指定脚本由bash
解释执行(若不写,系统会用默认Shell执行) - 注释信息:以
#
开头,说明脚本功能、作者、日期等(注释不执行,仅用于可读性) - 可执行语句:实际执行的命令(如
echo
、cd
、ls
等)
示例:第一个Shell脚本
#!/bin/bash
# 脚本名称:first.sh
# 功能:查看/boot目录下的内核文件
# 作者:XXX
# 日期:2024-05-XXcd /boot # 切换到/boot目录
echo "当前目录:$(pwd)" # 输出当前路径
echo "内核文件列表:"
ls -lh vml* # 查看以vml开头的内核文件
3. Shell脚本的执行步骤
步骤1:创建脚本文件
用vim
或nano
创建文件,如vim first.sh
,写入上述代码。
步骤2:赋予执行权限
Shell脚本需要可执行权限才能运行,通过chmod
命令设置:
chmod +x first.sh # 赋予所有用户执行权限
步骤3:执行脚本
Shell脚本有4种常见执行方式,适用于不同场景:
执行方式 | 命令示例 | 特点 | 适用场景 |
---|---|---|---|
路径执行 | ./first.sh 或 /home/xxx/first.sh | 需要执行权限,用脚本指定的解释器 | 正式环境、脚本部署 |
bash/sh 执行 | bash first.sh 或 sh first.sh | 无需执行权限,强制用bash/sh 解释 | 快速测试、脚本调试 |
source 执行 | source first.sh 或 . first.sh | 在当前Shell中执行(变量会生效) | 加载配置文件(如.bashrc ) |
管道执行 | `cat first.sh | bash` | 无需执行权限,通过管道传递脚本内容 |
注意:
source
执行与其他方式的区别
用./first.sh
或bash first.sh
执行时,会启动子Shell,脚本中定义的变量不会影响当前Shell;而source
会在当前Shell中执行,变量会生效(如执行source ~/.bashrc
加载环境变量)。
四、Shell变量:定义与使用
变量是Shell脚本的核心组件,用于存储数据(如路径、数值、字符串),方便后续调用和修改。
1. 变量的命名规则
Shell变量命名需遵守以下规则(违反会报错或导致异常):
- 首字符:必须是字母(a-z/A-Z) 或下划线(_),不能以数字开头
- 组成:只能包含字母、数字、下划线,不能有空格或特殊符号(如
$
、!
) - 大小写敏感:
name
和Name
是两个不同变量 - 禁止使用关键字:不能用Shell预留关键字(如
if
、for
、while
)
示例:合法与非法变量名
变量名 | 合法性 | 原因 |
---|---|---|
user_name | 合法 | 字母开头,下划线连接 |
_age | 合法 | 下划线开头 |
1score | 非法 | 数字开头 |
my name | 非法 | 包含空格 |
if | 非法 | 关键字 |
2. 变量的定义与赋值
基本语法
变量名=值 # 注意:等号前后不能有空格!
示例:定义不同类型的变量
# 字符串变量(值含空格时需用引号包裹)
name="Zhang San"
city='Beijing'# 数值变量
age=25
score=98.5# 命令结果赋值(用`命令`或$(命令))
current_dir=$(pwd) # 获取当前路径
file_count=`ls -l | wc -l` # 获取当前目录文件数
注意:字符串赋值的引号差异
- 双引号(
" "
):允许变量展开(如echo "Name: $name"
会输出Name: Zhang San
)- 单引号(
' '
):禁止变量展开(如echo 'Name: $name'
会输出Name: $name
)
3. 变量的使用
使用变量时,需在变量名前加$
符号,格式为$变量名
或${变量名}
(后者用于避免歧义)。
示例:变量的调用
name="Li Si"
echo "姓名:$name" # 输出:姓名:Li Si
echo "年龄:${age}岁" # 输出:年龄:25岁(${}避免与后续字符混淆)# 变量重新赋值
age=26
echo "更新后年龄:$age" # 输出:更新后年龄:26
4. 特殊变量:Shell内置变量
除了自定义变量,Shell还提供了内置特殊变量,用于获取命令行参数、执行状态等,常用如下:
变量 | 含义 | 示例 |
---|---|---|
$0 | 脚本文件名 | 执行./first.sh 时,$0 为./first.sh |
$1~$n | 命令行第1~n个参数 | 执行./test.sh a b c 时,$1=a 、$2=b |
$# | 命令行参数总数 | 上述示例中$#=3 |
$? | 上一条命令的执行状态(0=成功,非0=失败) | 执行ls 后echo $? 输出0,执行ls xxx 后输出2 |
$$ | 当前脚本的进程ID(PID) | echo $$ 输出脚本运行时的PID |
$! | 后台运行的最后一个进程的ID号 | echo $! 输出最后一个进程ID |
示例:使用特殊变量
#!/bin/bash
# 脚本名:ceshi.sh
echo "脚本名:$0"
echo "第1个参数:$1"
echo "第2个参数:$2"
echo "参数总数:$#"
echo "当前PID:$$"# 执行后查看结果
bash test.sh hello world
# 输出:
# 脚本名:test.sh
# 第1个参数:hello
# 第2个参数:world
# 参数总数:2
# 当前PID:12345
五、重定向与管道:Shell的“数据流控制”
在Shell脚本中,“重定向”和“管道”是处理命令输入输出的核心技术,常用于日志记录、结果过滤等场景。
1. 标准输入/输出/错误
Linux系统中,每个进程默认打开3个文件描述符(FD),对应不同的数据流:
文件描述符 | 名称 | 作用 | 默认设备 |
---|---|---|---|
0 | 标准输入(STDIN) | 接收命令的输入数据 | 键盘 |
1 | 标准输出(STDOUT) | 输出命令的正常结果 | 显示器 |
2 | 标准错误(STDERR) | 输出命令的错误信息 | 显示器 |
默认情况下,命令从键盘读入输入,将正常结果和错误信息都输出到显示器。而“重定向”就是改变这些数据流的方向(如输出到文件)。
2. 重定向操作
(1)输出重定向:> 与 >>
将命令的正常输出(STDOUT)保存到文件,而非显示器:
命令 > 文件名
:覆盖文件原有内容(若文件不存在则创建)命令 >> 文件名
:追加到文件尾部(不覆盖原有内容)
示例:输出重定向
# 将uname -r(内核版本)的结果覆盖保存到kernel.txt
uname -r > kernel.txt# 将date(当前时间)的结果追加到kernel.txt
date >> kernel.txt# 查看结果
cat kernel.txt
# 输出:
# 3.10.0-1160.el7.x86_64
# 2024年 05月 20日 星期一 15:30:00 CST
(2)错误重定向:2> 与 2>>
将命令的错误信息(STDERR)保存到文件,常用于收集错误日志:
命令 2> 文件名
:覆盖错误日志命令 2>> 文件名
:追加错误日志
示例:错误重定向
# 尝试查看不存在的文件,将错误信息保存到error.log
ls /xxx/yyy 2> error.log# 查看错误日志
cat error.log
# 输出:ls: 无法访问/xxx/yyy: 没有那个文件或目录
(3)混合重定向:&> 与 2>&1
将“正常输出”和“错误信息”保存到同一个文件:
命令 &> 文件名
:覆盖保存所有输出命令 > 文件名 2>&1
:等价于&>
,先将STDOUT输出到文件,再将STDERR重定向到STDOUT
示例:混合重定向
# 将ls的正常结果和错误信息都保存到all.log
ls /etc/passwd /xxx/yyy &> all.log# 查看结果
cat all.log
# 输出:
# /etc/passwd
# ls: 无法访问/xxx/yyy: 没有那个文件或目录
(4)输入重定向:<
将命令的输入来源从键盘改为文件:
命令 < 文件名
:命令从文件读取输入,而非等待键盘输入
示例:输入重定向
# 1. 创建密码文件(注意:实际生产中不建议明文存储密码)
echo "123456" > pass.txt# 2. 给用户jerry设置密码,从pass.txt读取密码(避免交互式输入)
passwd --stdin jerry < pass.txt
# 输出:更改用户 jerry 的密码 。
# 密码更改成功。
3. 管道操作:|
管道(|
)是Shell中最强大的功能之一,它能将左侧命令的输出作为右侧命令的输入,实现多命令协同工作。
语法:命令1 | 命令2 | 命令3
示例:管道的常见用法
# 1. 查找系统中安装的httpd相关包
rpm -qa | grep httpd# 2. 查看根目录磁盘使用率(过滤根分区,提取使用率数值)
df -h | grep "/$" | awk '{print "根目录使用率:" $5}'# 3. 统计/var/log目录下.log文件的总行数
ls /var/log/*.log | xargs cat | wc -l
管道的核心价值:拆分复杂任务
比如“统计根目录使用率”,若不用管道,需要先执行df -h
,手动找到根分区行,再提取使用率;用管道则可一步完成,且便于整合到脚本中自动化执行。
六、总结与实践建议
1. 核心知识点回顾
- Shell定位:命令解释器,连接用户与内核,适合自动化脚本开发
- 脚本规范:必须有
#!/bin/bash
声明,多写注释,变量命名遵循蛇形命名法(如user_name
) - 执行方式:路径执行(需权限)、
bash
执行(无需权限)、source
执行(当前Shell生效) - 重定向与管道:控制数据流方向,实现日志记录、结果过滤等功能
2. 实践建议
- 从简单脚本入手:先写小脚本(如备份文件、查看系统信息),熟悉语法后再写复杂逻辑
- 重视注释:脚本不仅是给机器执行的,更是给人看的,清晰的注释能减少后续维护成本
- 调试技巧:用
bash -x 脚本名
执行脚本,查看每一步命令的执行过程(如bash -x first.sh
) - 安全意识:避免在脚本中明文存储密码,执行未知脚本前先查看内容(
cat 脚本名
),防止恶意代码
通过本文的学习,你已经掌握了Shell脚本的核心基础。后续可进一步学习流程控制(if
、for
、while
)、函数、数组等高级特性,逐步编写更强大的自动化脚本。