目录

前言

一、shell基础入门

1.1 编程语言概述

1.2 什么是shell

1.3 shell脚本的概念

二、shell脚本的编写与执行

2.1 shell脚本的构成

2.2 创建脚本的流程

2.3 执行方法

三、变量基础

3.1 什么是变量

3.2 变量的引用和输出

3.3 echo的高级用法

四、特殊变量赋值

4.1 单引号和双引号

4.2 反撇号与命令替换

4.3 read命令

五、变量运算

5.1 expr命令

5.2 变量运算

5.3 $[]和$(())

5.4 let命令

5.5 bc命令

六、变量类型与作用范围

6.1 自定义变量和环境变量

6.2 只读变量

6.3 位置变量

6.4 预定义变量

6.5 export命令

七、重定向与管道

7.1 标准输入输出和错误输出

7.2 输出重定向

7.3 输入重定向

7.4 管道操作

7.5 综合应用实例

总结


前言

Shell 脚本编程是 Linux 运维和开发人员必备的核心技能之一。作为用户与操作系统内核之间的桥梁,Shell 不仅是一系列命令的简单堆砌,更是一门功能完备的编程语言。它能够将繁琐的手动操作转化为高效的自动化流程,让重复性工作变得简单可靠。

一、shell基础入门

1.1 编程语言概述

编程语言是人与计算机沟通的桥梁,根据设计思想应用场景,主要分为两大类:

面向过程语言 —— 像做菜谱
强调“按步骤执行”,把问题拆解成一系列有序的步骤或函数。

  • 代表语言:C语言、Shell脚本

  • 适用场景:系统底层开发、自动化运维、任务编排

面向对象语言 —— 像搭积木
强调“以对象为中心”,将数据和行为封装成“类”,通过对象间的交互来构建系统。

  • 代表语言:Java、Python

  • 适用场景:大型企业级应用、复杂业务逻辑开发

1.2 什么是shell

Shell 能做什么?(定位与能力)

Shell 是用户与内核之间的翻译官,是 Linux 系统中的“万能瑞士军刀”,既是命令解释器,也是一种编程语言。它的核心价值体现在三个层面:

能力 说明
命令翻译 将用户输入的命令解释并传递给内核,是用户与操作系统内核之间的“翻译官”。
输入输出管理 控制数据的流向(标准输入/输出/错误),并支持重定向和管道,实现命令间的协同。
编程能力 支持变量、条件判断、循环、函数等编程要素,可将多条命令编写成脚本,实现复杂任务的自动化。

典型应用场景

  • 软件安装与配置自动化(如一键部署LNMP环境)

  • 批量用户管理与权限设置

  • 系统日志分析与定时备份

  • 服务器资源监控与告警

常见的shell类型:

  • /bin/bash      默认shell

  • /bin/sh      是指向 /bin/bash 的软链接

  • /bin/tcsh      是 csh(C Shell)的增强版。它的语法更接近 C 语言

查看 shell

1. 查看当前所使用的 shell 

echo $SHELL

2. 查看系统支持的所有 shell

cat /etc/shells

1.3 shell脚本的概念

Shell脚本,简单说就是把一堆要在终端敲的Linux命令,按顺序写到一个文本文件里,然后一次性交给Shell解释器去执行。它是一种解释型、面向过程的脚本编程语言,功能是把“手动操作”变成“自动执行”。

#!/bin/bash                                   脚本声明
# 这是一个最简单的脚本              注释
echo "当前时间:"                        命令
date

二、shell脚本的编写与执行

2.1 shell脚本的构成

shell 由三部分构成

结构元素 写法示例 作用
1. 解释器声明(Shebang) #!/bin/bash 必须放在第一行。告诉操作系统用哪个解释器来执行这个脚本。没有这行,系统会猜,容易出错。
2. 注释说明

# 作者:张三

# 功能:备份日志

以 # 开头,给人看的信息。脚本的名称、作者、功能、用法最好都写在开头,方便维护。
3. 可执行命令

echo "ni hao"

pwd

脚本的正文,按从上到下的顺序依次执行。你在终端能敲的命令,都可以写在这里。

2.2 创建脚本的流程

创建文件     →     添加权限     →     检查语法     →     执行脚本

vim xxx.sh          chmod +x               bash -n               ./xxx.sh

创建 shell 脚本

2.3 执行方法

执行方式 命令示例 需要执行权限 开子进程 变量保留
指定解释器

./xxx.sh

/xxx.sh

直接执行

bash xxx.sh

sh xxx.sh

source 执行 source xxx.sh
重定向执行 sh < xxx.sh

三、变量基础

3.1 什么是变量

变量是一个用来存放数据的“容器”,并且这个容器有一个名字,方便你随时存取里面的数据。

书写方式为:变量名=变量值(“=” 两边不能有空格)

定义变量 name 和 age

name="张三"

age=18

当 = 号两边有空格时,会当作命令来执行。

规则:

1. 只能包含字母,数字,下划线

2. 不能以数字开头

3. 区分大小写

3.2 变量的引用和输出

引用方法:在变量前加 $ 符号

name="张三"

age=18

echo $name

echo $age

{}符号使用

3.3 echo的高级用法

常用选项:

选项 作用 示例 输出效果
-n 不换行(输出末尾不加换行符) echo -n "内容:" 光标停在  后面,等待输入,不会换到下一行。
-e 识别转义字符(如 \n 换行、\t 制表符) echo -e "a\nb" 输出两行:
a
b

常用转义字符:

转义字符 实际效果
\n → 换行 echo -e "a\nb" 输出两行
\t → 制表符 echo -e "a\tb" 输出 a b(中间有 Tab 空格)
\c → 不换行 echo -e "a\cb" 输出 ab 被忽略)
\b → 退格 echo -e "123\b456" 输出 12456(删除了 3
\\ → 输出 \ echo -e "路径\\home" 输出 路径\home
\$ → 输出 $ echo -e "价格\$100" 输出 价格$100

四、特殊变量赋值

4.1 单引号和双引号

特性 双引号 "" 单引号 ' '
解析变量($var 解析,输出变量的值 不会解析,输出 $var 这个字符
解析转义符(\n \t 解析(部分生效) 不会解析,原样输出反斜杠
解析命令替换(`cmd` 或 $(cmd) 执行命令并替换结果 不会执行,原样输出
内部是否还能用引号 可以用转义的双引号或单引号 内部不能再出现单引号(即使转义也不行)

name="张三"

单引号:

双引号:

单引号会把内容原样输出,双引号会输出变量值

4.2 反撇号与命令替换

`` 的作用是把命令输出到变量里

用法:

1. ``

time=`date +%T`

echo "当前时间:$time"

2. $()

time=$(date +%T)

echo "当前时间:$time"

4.3 read命令

read 命令输入交互式输入命令。

read -p "请输入姓名:" name

echo "你好,$name"

常用选项

选项 作用 典型示例 补充说明
-p 显示提示信息 read -p "请输入姓名:" name 替代 echo + read,更简洁,推荐优先使用
-n 限制输入字符数 read -n 11 phone 输入满 N 个字符后自动结束,无需按回车;少于 N 个则需手动回车确认
-s 静默模式(输入不可见) read -s -p "请输入密码:" pwd 常用于密码输入;注意:结束后需手动 echo 换行,否则后续输出会紧贴光标
-t 设置超时时间(秒) read -t 5 input 超时后 read 自动退出,可通过 $? 判断是否超时(非0即为超时)

五、变量运算

5.1 expr命令

expr 是 Linux/Unix 中一个非常古老的表达式计算命令,用于在 Shell 中进行整数运算、字符串操作和逻辑判断。

1. expr 10 + 55 (运算符两边必须有空格)

2. 乘法需要转义

5.2 变量运算

expr 同样支持变量运算:

x=10     y=20

expr $X + $Y # 输出:30
expr $X - $Y # 输出:-10
expr $X \* $Y # 输出:200
expr $X / $Y # 输出:0
expr $X % $Y #输出:10

5.3 $[]和$(())

比expr更简洁:乘法不用转义!

1. $[]

echo $[5 * 6]

2. $(())

echo $((5 * 6))

三种方法对比:

方式 乘法需转义 变量前 $ 是否必须 推荐指数 说明
expr ✅ 必须(\* ✅ 必须($var ★★☆ 老式外部命令,性能较差,仅维护旧脚本时使用
$[] ✗ 不需要 ⚠️ 可省略,但建议保留 ★★★ 已废弃,但某些老版本 Shell 仍支持;不推荐新脚本使用
$(( )) ✗ 不需要 ⚠️ 可省略,但建议保留 ★★★★★ 现代脚本首选,POSIX 标准,性能好,语法清晰

5.4 let命令

let 命令会直接修改变量本身。

num=20

let num=num+10

echo $num

简写方式

num=10

let num+=5 # num = num + 5 = 15
let num-=3 # num = num - 3 = 12
let num*=2 # num = num * 2 = 24

自增自减:

num=10
let num++ # num变成11
let num-- # num变成10

幂运算(let特有):

let num=num**10 # 2的10次方,num变成1024

5.5 bc命令

bc 命令可以计算小数,而 expr 只能计算整数。

echo "scale=2; 10/3" | bc

其中:scale=2 表示保留2位小数

基本用法:

echo "scale=3; 10/3" | bc


echo "5^2" | bc


echo "sqrt(16)" | bc

逻辑运算:

echo "3 > 5" | bc # 输出:0(假)


echo "3 < 5" | bc # 输出:1(真)


echo "10 == 10" | bc # 输出:1(真)

六、变量类型与作用范围

6.1 自定义变量和环境变量

在 Linux Shell 中,自定义变量和环境变量的本质区别在于:能否被子进程继承。

对比项 自定义变量(本地变量) 环境变量(全局变量)
作用范围 仅当前 Shell 进程有效 当前 Shell 及其所有子进程均有效
能否被子进程继承 ❌ 不能 ✅ 能
定义方式 var=value export var=value 或 declare -x var=value
查看所有 set(含所有变量和函数) env 或 export
删除 unset var unset var
生命周期 Shell 进程结束时销毁

同左,但子进程会复制一份副本

常见环境变量:

环境变量 含义 示例值
PATH 命令搜索路径 /usr/local/bin:/usr/bin:/bin
HOME 用户家目录 /home/zhangsan
SHELL 当前使用的 Shell /bin/bash
USER 当前用户名 zhangsan
PWD 当前工作目录 /home/zhangsan/project
OLDPWD 上一个工作目录 /home/zhangsan
LANG 系统语言编码 zh_CN.UTF-8
TERM 终端类型 xterm-256color
HOSTNAME 主机名 my-server

6.2 只读变量

readonly 是 Shell 中用于将变量或函数设为只读的内置命令。一旦设置为只读,变量的值不能再被修改,也不能被 unset 删除,直到当前 Shell 进程结束。

n=zdw      设置变量

echo $n      查看变量

readonly n      设置只读变量

n=zdw123      修改变量

6.3 位置变量

位置变量是 Shell 脚本中用于接收命令行传入参数的特殊变量。当你执行脚本时跟在脚本名后面的那些参数,就是通过位置变量来获取的。

$0 脚本名称(或当前 Shell 名称) ./test.sh
$1 第 1 个参数 ./test.sh hello → $1 = hello
$2 第 2 个参数 ./test.sh hello world → $2 = world
$3 ~ $9 第 3~9 个参数 $3$4……
${10} 第 10 个参数(必须加花括号 ${10}${11}……
$# 参数个数(不含 $0 ./test.sh a b c → $# = 3
$* 所有参数视为一个整体字符串 "$*" → "a b c"
$@ 所有参数视为独立的多个字符串 "$@" → "a" "b" "c"

sh first.sh zdw 123 456

6.4 预定义变量

预定义变量是 Shell 内置的特殊变量,用于获取脚本运行时的环境信息、进程状态、命令执行结果等。它们由 Shell 自动维护,无需定义即可直接使用

变量 含义 示例值 常用场景
$$ 当前 Shell 进程 PID 12345 创建唯一临时文件
$! 最后一个后台进程的 PID 12346 后台任务管理 / wait
$? 上一条命令的退出状态码 0(成功)或 1~255(失败) 判断命令执行结果

ls /etc/passwd

echo $? (输出 0 表示正确)

ls /etcpasswd

echo $? (输出 非0 表示错误)

6.5 export命令

export 是 Shell 中用于将变量或函数标记为环境变量(即导出到子进程)的内置命令。它是 Shell 变量作用域管理的核心工具。

基本用法:

七、重定向与管道

7.1 标准输入输出和错误输出

名称 文件描述符 符号 默认指向 用途
标准输入 0 < 或 << 键盘 读取数据(命令的输入来源)
标准输出 1 > 或 >> 终端屏幕 输出命令的正常结果
标准错误输出 2 2> 或 2>> 终端屏幕 输出命令的错误信息

7.2 输出重定向

输出重定向 就是将命令的标准输出(stdout) 和/或 标准错误输出(stderr) 从默认的屏幕改道到文件、设备或另一个命令。

1. 覆盖写入(危险:会清空原文件)
echo "第一行" > file.txt
cat file.txt          # 输出:第一行

echo "第二行" > file.txt
cat file.txt          # 输出:第二行(第一行被覆盖了!)

2. 追加写入(安全:保留原内容)
echo "第三行" >> file.txt
cat file.txt          # 输出:第二行\n第三行

3. 分离正确和错误输出:

ls /etc/passwd xxx > ok.txt 2> err.txt

7.3 输入重定向

输入重定向 就是改变命令的输入来源——从默认的键盘改道为文件字符串另一个命令的输出

# 统计文件行数(从文件读取)
wc -l < /etc/passwd      输出:30(/etc/passwd 的行数)

# 对比:不加 < 会把文件名显示出来
wc -l /etc/passwd      输出:30 /etc/passwd(包含文件名)

多行输入:

cat << EOF > config.txt
app_name=MyApp
version=1.0
EOF

7.4 管道操作

管道符 = 把多个命令串联起来

命令 功能 常见示例 补充说明
grep 过滤匹配的行 cat file | grep "error" 支持正则;-v 反选,-i 忽略大小写,-c 只计次数
sort 对行进行排序 cat file | sort -r 倒序,-n 按数字排序,-k 指定列,-t 指定分隔符
uniq 去重或统计重复次数 cat file | uniq -c 必须搭配 sort 使用(去重相邻行);-c 统计次数,-d 只显示重复行
wc 统计行数、字数、字符数 cat file | wc -l -l 行数,-w 单词数,-c 字节数,-m 字符数
cut 按列提取文本 cat file | cut -d: -f1 -d 指定分隔符,-f 指定列(支持 -f1,3 或 -f1-3),-c 按字符位置

1. 查找httpd包

rpm -qa | grep httpd

2. 统计访问量最高的10个IP

cat /var/log/httpd/access_log | awk '{print $1}' | sort | uniq -c | sort -rn | head -10

7.5 综合应用实例

自动化备份脚本

#!/bin/bash
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d)

# 创建备份目录(如果不存在)
mkdir -p "$BACKUP_DIR"

# 执行备份,将错误输出重定向到 error.log
tar -czf "${BACKUP_DIR}/backup_${DATE}.tar.gz" /home 2> "${BACKUP_DIR}/error.log"

# 判断备份是否成功
if [ $? -eq 0 ]; then
    echo "备份成功!"
else
    echo "备份失败,请查看错误日志!"
fi

执行脚本

sh file01.sh

总结

本文章系统梳理了 Shell 编程的核心知识体系,涵盖以下四个主要方面:

一、Shell 基础与脚本编写

明确了 Shell 作为命令解释器和编程语言的双重身份,掌握了脚本的三要素构成(Shebang 声明、注释说明、可执行命令),以及四种执行方式(直接执行、指定解释器、source 执行、重定向执行)的区别,其中 source 执行会在当前 Shell 中运行,变量得以保留。

二、变量体系

  • 变量基础:定义了变量的命名规则与引用方式($变量名),掌握了 echo 的 -n(不换行)和 -e(识别转义)选项。

  • 变量类型:区分了自定义变量(仅当前 Shell 有效)与环境变量(可通过 export 传递给子进程),了解了只读变量(readonly)的不可修改特性。

  • 特殊变量:掌握了位置变量($0~$9$#$@$*)用于接收脚本参数,以及预定义变量($$$!$?)用于获取进程信息和命令执行状态。

  • 引号规则:单引号原样输出不解析变量,双引号会解析变量和转义符。

三、运算与交互

  • 变量运算:对比了 expr(老式,需转义)、$(( ))(现代推荐,整数运算)和 bc(支持浮点数)三种方式,明确日常开发优先使用 $(( )) 和 bc

  • 交互输入:通过 read 命令配合 -p(提示)、-s(静默)、-t(超时)、-n(限制字符数)实现灵活的交互式输入。

四、输入输出与数据处理

  • 标准流与重定向:理解了标准输入/输出/错误(文件描述符 0/1/2)的分离设计,掌握了输出重定向(>>>2>&>)和输入重定向(<<<<<<)的用法。

  • 管道与文本处理:通过管道符 | 串联多个命令,结合 grep(过滤)、sort(排序)、uniq(去重统计)、wc(统计)、cut(提取列)等工具,实现强大的数据处理流水线。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐