linux_3阶段_shell编程_2

TJCcc 发布于 2026-01-01 50 次阅读


一、 数值运算 (Numerical Operations)

Shell中进行数值运算有多种方式,每种方式有其特定的应用场景和优缺点。

1. 常见运算方式对比

运算方式语法示例支持小数效率说明
$(())echo $((1+1))❌ 否⭐⭐⭐⭐⭐推荐。Shell内置,效率最高,无需转义 *
$[]echo $[1+1]❌ 否⭐⭐⭐⭐较老式的写法,功能同 $(())
exprexpr 1 + 1❌ 否⭐⭐⭐外部命令,效率较低。注意运算符两边必须有空格,* 需要转义为 \*
letlet i++❌ 否⭐⭐⭐⭐主要用于变量赋值和自增/自减操作。
bcecho "1.5+1" | bc✅ 是⭐⭐任意精度计算器,适合浮点数运算。
awkecho 10 3 | awk '{print $1/$2}'✅ 是⭐⭐文本处理神器,也擅长数值计算。
pythonpython -c "print(1+1)"✅ 是调用Python解释器,功能最强但开销大。

2. 深入解析

2.1 expr 命令的坑

  • 空格敏感expr 1+1 不会进行计算,只会输出字符串 1+1。必须写成 expr 1 + 1
  • 乘法转义expr 2 * 3 会报错,因为 * 是通配符。必须写成 expr 2 \* 3
  • 返回值expr 常用于判断参数是否为整数。如果计算结果非空且非0,返回码为0(成功);否则可能非0。

2.2 let 命令技巧

let 不需要 $ 符号来引用变量,非常适合循环中的计数器。

let i++   # 等同于 i=$((i+1))
let a=a+5

2.3 小数运算 (bc & awk)

Shell原生不支持小数,需借助工具:

# 使用 bc
echo "10 / 3" | bc -l  # -l 加载数学库,支持小数

# 使用 awk (推荐,格式化输出更方便)
echo 10 3 | awk '{printf "%.2f\n", $1/$2}'  # 输出 3.33

二、 变量子串操作 (String Manipulation)

Shell 提供了强大的内置字符串处理功能,无需调用 sedawk 即可完成简单的替换和截取,效率极高。

1. 字符串截取与删除

假设变量 url="www.sina.com.cn"

符号记忆口诀示例结果说明
#键盘上 #$ 左边 -> 从左往右${url#*.}sina.com.cn非贪婪匹配(最短匹配),删掉第一个 . 及其左边
##两个 # -> 贪婪${url##*.}cn贪婪匹配(最长匹配),删掉最后一个 . 及其左边 (常用于获取后缀)
%键盘上 %$ 右边 -> 从右往左${url%.*}www.sina.com非贪婪匹配,删掉最后一个 . 及其右边
%%两个 % -> 贪婪${url%%.*}www贪婪匹配,删掉第一个 . 及其右边

2. 字符串替换

语法说明示例 (url=www.baidu.com)结果
${var/old/new}替换第一个匹配项${url/baidu/sina}www.sina.com
${var//old/new}替换所有匹配项${url//w/W}WWW.baidu.com
${var/old/}删除第一个匹配项${url/baidu/}www..com

3. 获取长度

echo ${#url}  # 输出字符串长度

三、 条件表达式 (Conditional Expressions)

1. 语法结构

  • test 表达式
  • [ 表达式 ]:最常用,注意 [ 后和 ] 前必须有空格。
  • [[ 表达式 ]]:Bash 扩展语法,支持正则匹配 ~=,逻辑运算符 && || 可直接在内部使用。

2. 文件判断 (File Tests)

参数说明记忆
-f判断是否为普通文件 (file) 且存在file
-d判断是否为目录 (directory) 且存在directory
-e判断文件或目录是否存在 (exist)exist
-r判断是否有权限read
-w判断是否有权限write
-x判断是否有可执行权限execute

3. 字符串比对

运算符说明示例
= / ==相等[ "$a" = "$b" ]
!=不等[ "$a" != "$b" ]
-z长度为0 (Zero)[ -z "$name" ] (判断空变量)
-n长度不为0 (Non-zero)[ -n "$name" ]
=~正则匹配 (仅 [[ ]])[[ "$name" =~ ^[0-9]+$ ]]

4. 整数比对

运算符英文全称含义
-eqequal等于
-nenot equal不等于
-gtgreater than大于
-gegreater or equal大于等于
-ltless than小于
-leless or equal小于等于

5. 逻辑运算符

关系[ ] 内部语法[[ ]] 或 外部语法说明
与 (AND)-a&&两边都成立才为真
或 (OR)-o||只要一边成立即为真
非 (NOT)!!取反

示例:

[ -f /etc/hosts -a -d /etc ] && echo "Ok"  # [ ] 内部用 -a
[ -f /etc/hosts ] && [ -d /etc ] && echo "Ok" # 外部用 &&
[[ -f /etc/hosts && -d /etc ]] && echo "Ok" # [[ ]] 内部用 &&

四、 实战案例 (Practical Examples)

案例 1:检查输入是否为整数

利用正则匹配 [[ =~ ]] 是最简便的方法。

#!/bin/bash
read -p "请输入一个数字: " num

# 判断是否为纯数字
if [[ ! "$num" =~ ^[0-9]+$ ]]; then
    echo "错误:请输入纯整数!"
    exit 1
fi

echo "你输入的数字是:$num"

案例 2:磁盘空间监控告警

监控根分区使用率,超过 10% (测试用,实际可设 80%) 发送告警。

#!/bin/bash
# 1. 获取磁盘使用率 (去除百分号)
disk_use=$(df -h | awk '/\/$/ {print $(NF-1)}' | sed 's/%//')

# 2. 判断是否超过阈值
if [ "$disk_use" -gt 10 ]; then
    echo "警告:磁盘使用率过高,当前为 ${disk_use}%"
    # 此处可调用发送邮件或微信脚本
    # python weixin.py "Disk Alert" "Usage: ${disk_use}%"
else
    echo "磁盘状态正常:${disk_use}%"
fi

案例 3:服务自愈脚本 (Nginx)

判断服务是否存在,不存在则尝试启动。

#!/bin/bash
# 检查 Nginx 进程是否存在
# wc -l 统计行数,如果为0说明没运行
count=$(ps -ef | grep nginx | grep -v grep | wc -l)

if [ "$count" -eq 0 ]; then
    echo "Nginx 未运行,正在尝试启动..."
    systemctl start nginx

    # 再次检查
    if [ $? -eq 0 ]; then
        echo "Nginx 启动成功"
    else
        echo "Nginx 启动失败,请人工介入!"
    fi
else
    echo "Nginx 正在运行中"
fi

案例 4:自动创建目录

#!/bin/bash
DIR="/data/backup"

# 如果目录不存在,则创建
if [ ! -d "$DIR" ]; then
    echo "目录 $DIR 不存在,正在创建..."
    mkdir -p "$DIR"
fi

cd "$DIR" || exit
echo "已进入目录 $(pwd)"
唯有极致沉淀,才能造就辉煌。
最后更新于 2026-01-01