前言

Shell 是 Linux/Unix 系统的命令行解释器,也是运维工程师最核心的自动化工具。Shell 脚本本质是一个按顺序存放 Linux 命令的文本文件,加上变量、条件判断、循环和函数,就成了一门完整的编程语言,特别适合系统管理、软件部署、日志分析和定时任务等场景。相比其他编程语言,Shell 在调用系统命令、管理进程和处理文本方面有天然优势。

一、Shell介绍

1.1 Shell简介

Shell 是 一个用 C 语言编写的程序,是Linux系统中的一个命令行解释器,它是用户与操作系统内核之间的桥梁。简单说,就是你输入命令,Shell 负责理解并告诉内核去执行。

1.2 Shell三大功能

  • 命令翻译:把命令翻译成内核能懂的指令
  • 输入输出管理 :管理数据从哪来到哪去
  • 编程能力:把命令写成脚本自动执行

1.3 常见Shell类型

(1)/bin/bash:默认Shell,CentOS/RHEL都用它
(2)/bin/sh: bash的"祖先",已软链接到bash
(3)/bin/tcsh :C Shell增强版

1.4 Shell解释器

Linux 系统中存在多种 Shell 解释器,用户可通过以下命令查看系统中已安装的 Shell:

cat /etc/shells  #查看系统支持的所有Shell
echo $SHELL  #查看当前使用的Shell

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

二、Shell脚本编写与执行

2.1 Shell脚本的基本构成

部分 说明 示例
脚本声明 告诉系统用什么解释器 #!/bin/bash
注释 代码说明,不被执行 # 这是注释
命令 实际执行的语句 echo “hello”

2.2 编写 Shell 脚本

使用文本编辑器(如 vi)创建一个新文件,扩展名通常为 .sh

#!/bin/bash
echo "Hello World"

#! 是一个约定标记,指定脚本使用的解释器路径。
echo 用于向窗口输出文本。
在这里插入图片描述
在这里插入图片描述

2.4 创建脚本四步流程

  • 创建文件 :vim f01.sh
  • 添加权限 :chmod +x f01.sh
  • 检查语法 :bash -n f01.sh
  • 执行脚本:./f01.sh

2.3 执行 Shell 脚本

  • 执行脚本前需赋予执行权限:
chmod +x ./f01.sh

在这里插入图片描述

  • 执行方式有四种(最常用的是前两种):
    sh f01.sh(作为解释器参数执行)
    ./f01.sh(当前目录下执行)
    source f01.sh(source执行)
    sh < f01.sh (重定向执行)
    在这里插入图片描述
  • source和bash区别
    (1)bash 会创建子进程执行,脚本里的 cd、export、变量赋值等操作,只对子 Shell 生效。脚本执行完毕,子 Shell 销毁,当前终端环境完全不变。
    (2)source不会创建子 Shell,直接在当前的 Shell 中逐行执行,不会创建子 Shell,直接在当前的 Shell 中逐行执行。脚本里的 cd、export、变量赋值等操作,会直接影响当前终端。

三、Shell 程序:变量

3.1 语法格式

变量定义格式:变量名=值(等号两侧不能有空格)

  • 命名规则
    (1)只能包含字母、数字、下划线
    (2)不能以数字开头
    (3)区分大小写

3.2 变量使用

利用 $变量名${变量名} 使用变量。

#!/bin/bash
name="小明"
age=18
echo $name
echo $age
echo "my name is$name ,age is${age}"    
#变量后面紧跟着其他字符(比如字母、数字、下划线)时,就必须用花括号{}把变量名括起来,告诉 Shell 哪部分是变量名,哪部分是普通文本。

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

3.3 echo命令高级用法

  • 选项含义
选项 作用 示例
-n 不换行 echo -n “请输入”
-e 识别转义符 echo -e “a\nd”
  • 常用转义字符:最常用是\n\t
字符 含义
\n 换行
\t 制表符
\c 不换行
\b 退格
\ \ 输出\本身
\$ 输出$本身

在这里插入图片描述

四、特殊变量赋值

4.1 双引号和单引号

  • 双引号识别变量,单引号不识别变量
    在这里插入图片描述
    :需要变量值时用双引号,需要原样输出时用单引号

4.2 反撇号与命令替换

作用:把命令输出存到变量里

4.2.1 反撇号

time=`date +%T`
echo "$time"

在这里插入图片描述

4.2.2 $()

$()更容易嵌套

 echo "今天日期:$(date +%Y年%m月%d日)"

在这里插入图片描述

4.3 read交互式输入命令

常用选项

  • -p:显示提示
  • -n:限制字符数
  • -s:静默输入(输入密码)
  • -t:超时秒数
#!/bin/bash
read -p "请输入名字:" name
echo "你好,$name"
read -n 11 -p "请输入手机号:" phone
echo ""
echo "$phone"
read -s -p "请输入密码:" pwd
echo "$pwd"

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

五、变量运算

5.1 expr

expr 是一款表达式计算工具,它能完成表达式的求值操作。

expr 1 + 1  #运算符两边必须有空格
expr 2 \* 3  #乘法需要转义
expr 10 % 3  #取余
a=5
b=3
expr $a + $b  #expr也支持变量运算
sum=`expr $a + $b`  #用反撇号把结果存为变量
echo $sum
sum=$(expr $a + $b)   #用$()把结果存为变量
echo $sum

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

5.2 $[ ] 和 $(())

echo $[2 * 3]   #用$[]不需要把乘法转义
echo $((2 * 3))   #用$(())不需要把乘法转义
a=9
b=6
echo $[a + b]
echo $((a - b))
echo $[a * b]  
echo $[a / b]

在这里插入图片描述

  • 三种方式对比:
方式 乘法转义 变量$
expr 需要 需要
$[] 不需要 可省略
$(()) 不需要 可省略

5.3 let命令——直接修改变量

  • let会修改变量本身
num=5
let num=num+4   #此时num变为9
echo $num  #输出num为9
num=5
let num+=5  #此时num变为10
echo $num  #输出num为10
let num-=4  #此时num为10-4=6
echo $num  #输出num为6
let num*=2  #此时num为6*2=12
echo $num   #此时num为12

在这里插入图片描述

  • let自增自减
num=15
let num++   #此时num为16
echo $num   #输出为16
let num--   #此时num为16-1=15
echo $num   #输出为15

在这里插入图片描述

  • let幂运算(特有)
num=2
let num=num**10   #2的10次方,num变为1024
echo $num   #输出为1024

在这里插入图片描述

5.4 bc计算器——浮点运算

5.4.1 expr只能计算整数,而bc可以计算小数(基本用法)

echo "scale=2; 10/3" | bc   #scale=2 表示保留2位小数,输出为3.33
echo "4^2" | bc   #表示4的2次方,输出为16
echo "sqrt(16)" | bc   #表示为16开根号,输出为4
r=5
echo "3.14159 * $r * $r" | bc   #表示为3.14159*5*5,输出为78.53975
  • scale只对除法有效
    在这里插入图片描述

5.4.2 bc逻辑运算(返回0或1)

echo "3>5"|bc   #输出为0(假)
echo "3<5"|bc   #输出为1(真)
echo "10 == 10"|bc  #输出为1(真)

在这里插入图片描述

六、变量类型与作用范围

6.1 自定义变量与环境变量

  • 自定义变量:用户自己定义的变量
  • 环境变量:系统预定义的
  • 常见环境变量:
变量 含义
echo $USER 当前用户名
echo $HOME 用户主目录
echo $PWD 当前工作目录
echo $SHELL 默认Shell
echo $LANG 系统语言
echo $RANDOM 随机数(0-32767)
echo $UID 用户ID
echo $PATH  #命令搜索路径,查看PATH

在这里插入图片描述
注:PATH=“” 会让所有命令失效!

6.2 只读变量

readonly PI=3.1415926  #设置只读变量
PI=3.14  #结果报错,只读变量不能改变
unset PI  #只读变量无法删除

在这里插入图片描述

6.3 位置变量

#!/bin/bash
echo "脚本名称:$0"
echo "第一个参数:$1"
echo "第二个参数:$2"
echo "第三个参数:$3"
echo "参数总数:$#"
echo "所有参数(\$*):$*"
echo "所有参数(\$@):$@"
ls /etc > /dev/null
echo "ls /etc 的返回值:$?"  # 返回值为0则上一条命令正确,返回值大于0则上一条命令错误
ls /abc > /dev/null 2>&1
echo "ls /abc 的返回值:$?"
echo "当前Shell进程PID:$$"
sleep 100 &
echo "后台进程PID:$!"

在这里插入图片描述

6.4 预定义变量

常用预定义变量

  • $?:上一条命令的返回状态(0=成功,非0=失败)
  • $$:当前进程的进程号
  • $!:最后一个后台进程的进程号
ls /etc > /dev/null
echo "ls /etc 的返回值:$?"  # 返回值为0则上一条命令正确,返回值大于0则上一条命令错误
ls /abc > /dev/null 2>&1
echo "ls /abc 的返回值:$?"
echo "当前Shell进程PID:$$"
sleep 100 &
echo "后台进程PID:$!"

在这里插入图片描述

6.5 export命令

name="李四"
bash                  # 进入子Shell
echo $name            # 无输出(子Shell看不到)
exit                  # 退出子Shell

export name           # 导出变量
bash                  # 进入子Shell
echo $name            # 输出:李四(子Shell能看到)

#export的三种用法
#方式1:先定义再导出
name="李四"
export name
#方式2:定义时直接导出
export city=beijing
# 方式3:export -n 取消导出
export -n name        # 取消后,子Shell又看不到了

在这里插入图片描述

七、重定向与管道

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

  • Linux的三条“流水线”
文件描述符 名称 默认设备 说明
0 STDIN 键盘 程序从这里读数据
1 STDOUT 显示器 正常输出到这里
2 STDERR 显示器 错误信息到这里

7.2 输出重定向

uname -p > kernel.txt   # > 覆盖:把输出保存到文件(覆盖原有内容)
uname -r >> kernel.txt  # >> 追加:把输出追加到文件末尾
ls /etc/passwd xxx > ok.txt 2> err.txt  # 正确的保存到ok.txt,错误的保存到err.txt
command > /dev/null 2>&1  # 忽略所有输出(正确+错误都丢弃)
echo $?   #输出值为0,则上一条命令正确

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

7.3 输入重定向

#输出到文件
cat > config.txt << EOF
app_name=MyApp
version=1.0
EOF
cat config.txt   #查看文件

在这里插入图片描述

7.4 管道操作

  • 常用管道命令
命令 功能
grep 过滤
sort 排序
uniq 去重/统计
wc 统计行/字/字符
cut 提取列
rpm -qa | grep httpd  # 查找httpd包
who | wc -l  # 统计当前登录用户数
cat test.txt | awk '{print $1}' | sort | uniq -c | sort -rn | head -3  # 统计文件中出现次数最高的3个水果
# awk '{print $1}':取每行第一个字段(通常是 IP)
# sort :排序,方便 uniq 统计
# uniq -c :统计每个 IP 出现次数
# sort -rn :按次数倒序排序
# head -10 :取前 10 条
cat /etc/passwd | grep "/bin/bash$" | cut -d: -f1   # 提取bash用户
# grep "/bin/bash$" 选择以/bin/bash结尾的行
# -d:指定以冒号为分割符
# -f1 取第一列

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

  • 常用管道组合
组合 含义
sort filename 按字母排序
sort -n filename 按数字排序
sort -r filename 倒序
sort file | uniq 去重
sort file |uniq -c 统计出现次数
sort file | uniq -d 只显示重复行

7.5 案例

7.5.1 案例一:自动化备份

#!/bin/bash
echo "CPU负载:$(uptime | awk '{print $10}')"  #打印第10列
echo "内存:$(free -h | awk 'NR==2{print $3"/"$2}')"
echo "磁盘:$(df -h | awk 'NR>1 && $5+0>80 {print "⚠ 磁盘"$1"使用率:"$5}')"  #行号>1(跳过标题行)且 第5字段数值>80,打印警告信息、第1字段(分区名)、第5字段(使用率%)

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

7.5.2 案例二:服务器健康检查

#!/bin/bash
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d)
tar -czf ${BACKUP_DIR}/backup_${DATE}.tar.gz /home 2>${BACKUP_DIR}/error.log  
#将 /home 目录打包压缩成带日期的 .tar.gz 文件,并把所有错误信息单独保存到日志文件中。
if [ $? -eq 0 ]; then
echo "✓ 备份成功!"
else
echo "✗ 备份失败,请查看错误日志"
fi

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

总结

本文系统介绍了Shell编程的核心基础知识。Shell既是命令解释器,也是脚本编程语言,在系统管理和自动化运维中应用广泛。

  • 脚本编写与执行:创建脚本文件后需赋予执行权限(chmod +x),可通过路径执行、bash调用或source方式运行,三种方式在子进程环境上有所区别。
  • 变量与字符串:变量定义无需声明类型,局部变量与环境变量作用域不同;单引号保留字面值,双引号支持变量解析。
  • 参数传递与运算符$#统计参数个数,$*将所有参数合并为单字符串,$@保持参数独立。同时掌握了算术运算、关系比较、逻辑操作及文件测试等各类运算符的使用方法。
Logo

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

更多推荐