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

shell脚本(略)

文章目录

  • Shell编程从入门到实战:一篇搞定脚本开发核心技能
    • 一、Shell基础:认识脚本的“灵魂”
      • 1.1 什么是Shell?
      • 1.2 常用Shell解释器
    • 二、快速入门:编写第一个Shell脚本
      • 2.1 脚本编写三步曲
        • 步骤1:创建脚本文件
        • 步骤2:编写脚本内容
        • 步骤3:赋予执行权限并运行
      • 2.2 脚本执行常见问题
    • 三、核心语法:变量与字符串
      • 3.1 变量定义与使用
        • 变量特殊操作
      • 3.2 字符串操作
        • 字符串常用操作
    • 四、参数传递:脚本接收外部输入
      • 4.1 基础参数示例
      • 4.2 特殊参数说明
        • `$*`与`$@`的区别
    • 五、流程控制:条件与循环
      • 5.1 if条件判断
        • 格式1:单支(满足条件执行)
        • 格式2:双支(二选一执行)
        • 格式3:多支(多选一执行)
        • 常用条件表达式
      • 5.2 for循环
        • 格式1:数值循环(适合固定次数)
        • 格式2:列表循环(适合遍历集合)
      • 5.3 while循环
        • 格式1:条件循环
        • 格式2:无限循环(死循环)
      • 5.4 case分支
    • 六、函数与数组:模块化与数据存储
      • 6.1 Shell函数
        • 函数定义格式
        • 函数调用与参数
      • 6.2 数组操作
        • 数组定义
        • 数组常用操作
    • 七、实战案例:猜数字游戏
    • 八、总结与拓展

Shell编程从入门到实战:一篇搞定脚本开发核心技能

在Linux系统运维与开发中,Shell脚本是提高效率的“利器”——它能将复杂的命令序列封装成可复用的程序,实现自动化操作。本文基于Shell编程核心知识,从基础概念到实战案例,带你系统掌握Shell脚本开发,适合零基础入门与进阶学习。

一、Shell基础:认识脚本的“灵魂”

1.1 什么是Shell?

Shell是用C语言编写的命令解释器,它作为用户与Linux内核之间的“桥梁”,支持两种核心能力:

  • 作为命令语言:直接在终端执行lscd等命令,与系统交互;
  • 作为程序设计语言:通过编写脚本(.sh文件),实现逻辑控制、循环、函数等复杂功能。

类比理解:Shell类似Windows的cmd.exe,但功能更强大,且是大多数Linux系统的默认交互工具。

1.2 常用Shell解释器

Linux支持多种Shell解释器,可通过cat /etc/shells查看系统已安装的Shell,其中:

  • /bin/bash最常用的Shell,易用且免费,是CentOS、Ubuntu等系统的默认解释器;
  • /bin/sh:POSIX标准的Shell,是bash的简化版;
  • /sbin/nologin:禁止用户登录的Shell(用于系统账号)。

后续所有案例均基于bash编写,脚本开头需通过#!/bin/bash指定解释器(“#!”是约定标记,告诉系统用哪个程序执行脚本)。

二、快速入门:编写第一个Shell脚本

2.1 脚本编写三步曲

以“打印Hello World”为例,完整流程如下:

步骤1:创建脚本文件

vivim编辑器新建文件(扩展名.sh仅为标识,不影响执行):

# 1. 创建存放脚本的目录(可选,建议规范管理)
mkdir shelldemo && cd shelldemo# 2. 新建脚本文件
vim hello.sh
步骤2:编写脚本内容

hello.sh中写入以下代码:

#!/bin/bash  # 指定解释器为bash
echo "Hello World!"  # 向终端输出文本
步骤3:赋予执行权限并运行

Shell脚本默认无执行权限,需通过chmod命令授权,再执行:

# 赋予当前用户执行权限
chmod u+x ./hello.sh# 执行脚本(三种方式)
./hello.sh          # 方式1:当前目录执行(推荐,需权限)
/root/shelldemo/hello.sh  # 方式2:全路径执行(需权限)
sh hello.sh         # 方式3:直接调用解释器(无需权限)

执行结果:终端输出Hello World!,表示第一个脚本运行成功。

2.2 脚本执行常见问题

  • 直接输入hello.sh报错?
    Linux会从PATH环境变量指定的目录中找命令,当前目录(.)默认不在PATH中,需用./hello.sh明确路径。
  • “权限不够”报错?
    未执行chmod +x授权,或用sh hello.sh绕开权限检查。

三、核心语法:变量与字符串

3.1 变量定义与使用

Shell变量无需声明类型,直接赋值即可,核心规则:

  • 格式:变量名=值等号两边无空格,空格会被解析为命令分隔符);
  • 命名规则:首字符为字母,可含字母、数字、下划线,不能用bash关键字(如iffor);
  • 使用方式:$变量名${变量名}(花括号用于明确变量边界,推荐加)。

示例:

#!/bin/bash
# 定义变量
your_name="bigdata.com"
age=20# 使用变量
echo $your_name       # 输出:bigdata.com
echo ${age}           # 输出:20
echo "My age is ${age}."  # 边界明确,避免歧义
变量特殊操作
  • 重新赋值:直接覆盖原有值,如your_name="hadoop"
  • 只读变量:用readonly标记,赋值后不可修改,如readonly age=20
  • 删除变量:用unset删除普通变量(只读变量不可删),如unset your_name

3.2 字符串操作

字符串是Shell中最常用的数据类型,支持单引号、双引号、无引号三种形式,差异如下:

引号类型特点示例输出结果
单引号原样输出,不解析变量和转义符str='I love $your_name'I love $your_name
双引号解析变量和转义符(如\nstr="I love $your_name"I love bigdata.com
无引号解析变量,但不保留空格str=I love $your_name报错(空格被解析为参数分隔)
字符串常用操作
  • 获取长度:${#字符串},如${#your_name}(计算"bigdata.com"的长度为11);
  • 提取子串:${字符串:起始索引:长度}(索引从0开始),如${your_name:3:4}(从第4个字符开始,取4个字符,结果为data);
  • 查找子串:用expr index "字符串" 子串(位置从1开始),如expr index "I am good at hadoop" am(输出3,表示“am”从第3个字符开始)。

四、参数传递:脚本接收外部输入

执行脚本时,可通过“脚本名+参数”的方式传递数据,脚本内通过$n获取(n为数字,$1是第一个参数,$0是脚本名)。

4.1 基础参数示例

编写demo1.sh脚本,接收并打印参数:

#!/bin/bash
echo "脚本名:$0"       # 输出脚本文件名
echo "第一个参数:$1"   # 输出第一个参数
echo "第二个参数:$2"   # 输出第二个参数
echo "参数总数:$#"     # 输出参数总数
echo "所有参数(字符串):$*"  # 所有参数合并为一个字符串

执行脚本并传递参数:

./demo1.sh 100 "hello"

输出结果:

脚本名:./demo1.sh
第一个参数:100
第二个参数:hello
参数总数:2
所有参数(字符串):100 hello

4.2 特殊参数说明

除了$0$1$#,还有几个常用特殊参数:

参数含义示例(接上述执行命令)
$*所有参数合并为一个字符串"100 hello"
$@所有参数分开为独立字符串"100" "hello"
$$脚本运行的进程ID(PID)如12345
$?上一条命令的退出状态(0=成功,非0=失败)0(表示./demo1.sh执行成功)
$*$@的区别
  • 不加引号时:两者均以$1 $2 ... $n形式输出,无差异;
  • 加引号时:"$*"合并为一个字符串,"$@"保留每个参数独立性(遍历参数时推荐用"$@")。

五、流程控制:条件与循环

5.1 if条件判断

Shell的if语句用于“分支选择”,支持单支、双支、多支三种格式,核心是条件表达式(需用[ ]包裹,括号内前后有空格)。

格式1:单支(满足条件执行)
#!/bin/bash
num=10
# 判断num是否为偶数
if [ $((num%2)) -eq 0 ]; thenecho "${num}是偶数"
fi
格式2:双支(二选一执行)
#!/bin/bash
num1=10
num2=20
if [ $num1 -gt $num2 ]; thenecho "${num1} > ${num2}"
elseecho "${num1} < ${num2}"
fi
格式3:多支(多选一执行)
#!/bin/bash
score=$1  # 从外部接收分数参数
if [ $score -ge 90 ]; thenecho "优秀"
elif [ $score -ge 80 ]; thenecho "良好"
elif [ $score -ge 60 ]; thenecho "及格"
elseecho "不及格"
fi

执行./score.sh 85,输出良好

常用条件表达式
  • 数字比较:-eq(等于)、-ne(不等于)、-gt(大于)、-lt(小于)、-ge(大于等于)、-le(小于等于);
  • 字符串比较:= (等于)、!=(不等于)、-z(空字符串)、-n(非空字符串);
  • 文件判断:-f(普通文件)、-d(目录)、-e(文件存在)、-x(可执行)。

5.2 for循环

for循环用于“重复执行一段代码”,Shell支持两种常用格式:

格式1:数值循环(适合固定次数)
#!/bin/bash
# 计算1-10的累加和
sum=0
for ((i=1; i<=10; i++)); dosum=$((sum + i))  # 算术运算,$((表达式))
done
echo "1-10累加和:${sum}"  # 输出:55
格式2:列表循环(适合遍历集合)
#!/bin/bash
# 遍历数组或列表
fruits=("apple" "banana" "cherry")
for fruit in ${fruits[@]}; do  # @表示所有元素echo "水果:${fruit}"
done# 遍历目录下所有文件(用*通配符)
for file in $(ls /root/shelldemo); doecho "文件:${file}"
done

5.3 while循环

while循环通过“条件是否成立”控制循环,适合“不确定次数”的场景(如等待用户输入)。

格式1:条件循环
#!/bin/bash
# 输入yes/YES停止循环
y=""
while [ "$y" != "yes" -a "$y" != "YES" ]; do  # -a表示逻辑与echo "请输入yes/YES停止循环:"read y  # 接收键盘输入
done
echo "循环停止!"
格式2:无限循环(死循环)

while true实现,需在循环内加退出条件(如exit):

#!/bin/bash
while true; doecho "请输入字符串:"read yif [ "$y" == "yes" ]; thenexit 0  # 退出脚本,终止循环fi
done

5.4 case分支

case用于“多值匹配”,类似其他语言的switch-case,适合固定值判断(如参数匹配)。

示例:根据输入参数执行不同操作

#!/bin/bash
case $1 in"hello")echo "Hello World!";;  # 结束当前分支(类似break)"test")echo "Testing...";;"")echo "请输入参数(如./casedemo.sh hello)";;*)  # 默认分支,匹配所有未命中的值echo "默认操作";;
esac  # case的反向拼写,标记分支结束

执行./casedemo.sh test,输出Testing...;执行./casedemo.sh other,输出默认操作

六、函数与数组:模块化与数据存储

6.1 Shell函数

函数用于封装重复逻辑,实现代码复用,Shell函数需“先定义,后调用”。

函数定义格式
# 格式1:带function关键字
function 函数名() {函数体代码[return 返回值]  # 可选,返回值为0-255的整数
}# 格式2:简化版(推荐)
函数名() {函数体代码
}
函数调用与参数
  • 调用:直接写函数名,如print_hello
  • 参数传递:调用时跟在函数名后(如sum 10 20),函数内用$1$2获取(同脚本参数);
  • 返回值:用return返回整数,或用echo输出结果(推荐,支持任意类型)。

示例1:无参无返回值函数

#!/bin/bash
# 定义函数
print_hello() {echo "Hello"echo "你好"
}# 调用函数
print_hello

示例2:带参带返回值函数(计算两数之和)

#!/bin/bash
# 定义求和函数
sum() {result=$(( $1 + $2 ))echo $result  # 用echo输出结果(推荐)
}# 调用函数并接收结果
num1=10
num2=20
total=$(sum $num1 $num2)  # $(命令)捕获命令输出
echo "两数之和:${total}"  # 输出:30

6.2 数组操作

Shell仅支持一维数组,用于存储多个值,索引从0开始。

数组定义
# 方式1:直接赋值(元素用空格分隔)
fruits=("apple" "banana" "cherry")# 方式2:索引赋值(支持稀疏赋值)
fruits[0]="apple"
fruits[2]="cherry"  # 索引1可空
数组常用操作
  • 获取单个元素:${数组名[索引]},如${fruits[0]}(输出apple);
  • 获取所有元素:${数组名[*]}${数组名[@]}(同参数传递的$*$@);
  • 获取长度:${#数组名[*]}${#数组名[@]},如${#fruits[@]}(输出3);
  • 遍历数组:用for循环遍历所有元素,示例:
#!/bin/bash
fruits=("apple" "banana" "cherry")
# 遍历方式1:列表循环
for fruit in ${fruits[@]}; doecho $fruit
done# 遍历方式2:索引循环
len=${#fruits[@]}
for ((i=0; i<len; i++)); doecho ${fruits[$i]}
done

七、实战案例:猜数字游戏

基于前面的语法知识,编写一个互动性脚本——猜数字游戏,规则:

  1. 程序随机生成1-100的数字;
  2. 用户输入猜测值,程序提示“大了”“小了”或“猜对了”;
  3. 直到猜对,提示游戏结束。

完整代码(guess_number.sh):

#!/bin/bash
# 生成1-100的随机数(RANDOM是系统变量,0-32767)
num=$[RANDOM%100+1]# 无限循环,直到猜对
while true; do# 提示用户输入(-p指定提示语)read -p "计算机生成了1-100的随机数,你猜:" cai# 判断猜测结果if [ $cai -eq $num ]; thenecho "恭喜,猜对了!"exit 0  # 猜对,退出脚本elif [ $cai -gt $num ]; thenecho "不巧,猜大了~"elseecho "不巧,猜小了~"fi
done

执行./guess_number.sh,即可开始游戏,例如:

计算机生成了1-100的随机数,你猜:50
不巧,猜大了~
计算机生成了1-100的随机数,你猜:25
不巧,猜小了~
计算机生成了1-100的随机数,你猜:37
恭喜,猜对了!

八、总结与拓展

本文覆盖了Shell编程的核心知识点:从基础脚本编写,到变量、流程控制、函数、数组,最后通过实战案例巩固应用。掌握这些内容后,可进一步学习:

  1. 文件包含:用source 文件名.加载其他脚本的变量/函数,实现代码复用;
  2. 正则表达式:结合grepsedawk处理文本数据;
  3. 自动化运维:编写脚本实现日志切割、服务启停、定时任务(结合crontab)。

Shell脚本的核心价值是“自动化”——把重复的手动操作写成脚本,让计算机替你干活。多练多写(如批量处理文件、自动化部署),才能真正掌握这门技能。

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

相关文章:

  • 【Flink】并行度的设置
  • nrf52840 flash 分区
  • 3【鸿蒙/OpenHarmony/NDK】如何在鸿蒙应用中使用NDK?
  • 线阵相机和镜头选型案例介绍
  • 【不懂就问】-手机相关学习
  • 打开多个Excel文件后快速关闭所有的文档,并且退出Excel应用
  • Docker一小时快速上手(附报错解决方式)
  • 并发编程——11 并发容器(Map、List、Set)实战及其原理分析
  • deep seek的对话记录如何导出
  • CICD实战(1) - 使用Arbess+GitPuk+Docker快速实现项目打包构建、docker部署
  • 视频理解与行为识别全景综述
  • 计算机网络:(十六)TCP 的运输连接管理
  • 传统数据库out啦!KINGBASE ES V9R1C10 开启国产数据库“修仙”新纪元!
  • Redis六大常见命令详解:从set/get到过期策略的全方位解析
  • 大模型推理技术解析
  • AI热点周报(8.24~8.30):Grok 2.5开源,OpenAI Realtime正式商用,Meta或与OpenAI或Google合作?
  • 学习记录(二十二)--Overleaf中生成的PDF左上角1.5em问题
  • 【stm32】对射式红外传感器计次以及旋转编码器计次
  • 基于单片机智能大棚/温室大棚/智慧农业/智能栽培种植系统/温湿度控制
  • 使用VBA实现快速多重数据筛选
  • Flink部署实战:从入门到优化
  • 第 14 篇:K-Means与聚类思维——当AI在没有“标准答案”的世界里寻宝
  • python实现滤波器的简单案例
  • python如何打开显示svg图片
  • 阿里云-应用实时监控服务 ARMS
  • Unity笔记(九)——画线功能Linerenderer、范围检测、射线检测
  • AFSIM仿真脚本生成(三)脚本解析技术加速验证过程
  • Linux 系统都有哪些
  • HikariCP vs DBCP2 vs Tomcat JDBC:多场景数据库连接池方案对比与实践指南
  • 大模型RAG项目实战:Milvus向量数据库