一、理论
1.Shell脚本编程规范
(1)Shell简介
Linux 系统中的 Shell 是一个特殊的应用程序,它介于操作系统内核与用户之间,充当 了一个“命令解释器”的角色,负责接收用户输入的操作指令(命令)并进行解释,将需要执 行的操作传递给内核执行,并输出执行结果。
(2)Shell脚本的概念及处理逻辑
① Shell脚本
1)将要执行的命令按顺序保存到一个文本文件
2)给该文件可执行权限
3)可结合各种Shell控制语句完成更复杂的操作
② 处理处理
1)顺序执行:程序按从上到下的顺序执行
2)选择执行:程序执行过程中,根据条件的不同选择不同的分支继续执行
3)循环执行:程序在执行过程中需要重复执行多次某些语句(根据已知次数、已知条件)
辑
(3)Shell脚本的应用场景
① 重复性操作
② 交互性任务
③ 批量事务处理
④ 服务允许状态监控
⑤ 定时任务执行
(4)运行Shell脚本的四种方式
调试阶段,可以不赋权执行:
① sh first.sh
② bash first.sh
③ source first.sh (全量查询,结束自动切换目录
正式上线,必须赋权执行:
chmod 777 first.sh
④ ./first.sh
(3)Shell的分类
sh:UNIX最初使用的 shell,已经被bash所替换。
bash:基准于GNU的框架下发展出的Shell,是 sh 的扩展。(/bin/bash)是目前大多数 Linux 版本采用的默认 Shell。
csh:语法有点类似于c语言的Shell。
tcsh:整合了csh,提供更多的功能。
nologin:奇怪的shell,这个shell可以让用户无法登录主机。
(4)Shell脚本的作用
① 自动化运维
② 批量化重复操作可以编写脚本结合计划任务自动周期运行
③ 减轻管理员工作量
④ 提高处理文本文件的速度
⑤ 避免配置出错
(5)管道操作
将管道符号“|”左侧的命令输出的结果,作为右侧命令的输入(处理对象),同一行命令中可以使用多个管道。
(6)重定向交互式硬件设备
类型 | 设备文件 | 文件描述编号 | 默认设备 |
标准输入 | /dev/stdin | 0 | 键盘 |
标准输出 | /dev/stdout | 1 | 显示器 |
标准错误输出 | /dev/stderr | 2 | 显示器 |
(5)重定向操作
类型 | 操作符 | 用途 |
重定向输入 | < | 从指定的文件读取数据 |
重定向输出 | > | 将标准输出结果 保存 到指定的文件,并且覆盖原有内容 |
>> | 将标准输出结果 追加 到指定的文件的尾部,不覆盖原有内容 | |
重定向错误输出 | 2> | 将错误信息 保存 到指定的文件,并且覆盖原有内容 |
2>> | 将错误信息 追加 到指定的文件的尾部,不覆盖原有内容 | |
混合输出 | &> | 将标准输出、标准错误保存到同一文件中 |
2>&1 | 将标准错误输出重定向到标准输出 |
2.Shell脚本变量揭秘
(1)变量的作用
变量用来存放系统和用户需要使用的特定参数(值)。
(2)自定义变量
① 定义新的变量
变量名:使用固定的名称,由系统预设或用户定义
1)不要使用系统的命令作为变量名
2)不要使用中文
3)不能特殊符号开头 可以用_来开头
4)在指定变量名的时候有一个默认的规则:书本:book 老师:teacher a= b=
5)要有注释,还要注意前后一致
变量值:
1)整数型:int
2)字符型:string
3) 布尔型:boolean
4)浮点型:float
② 查看和引用变量的值
通过在变量名称前添加前导符号“$”,可以引用一个变量的值。使用echo命令可以查看变量,可以在一条echo命令中同时查看多个变量值。
当变量名称容易和紧跟其后的其他字符混淆时,需要添加大括号“{}”将其括起来,否则将无法确定正确的变量名称。对于未定义的变量,将显示空值。
③ 变量赋值的特殊操作
1)赋值时使用引号:
双引号:允许通过$符号引用其他变量值。弱引用,其中的变量引用会被替换为变量值
单引号:禁止引用其他变量值,$视为普通字符。强引用,其中的变量引用不会被替换为变量值,而保持原字符串
反撇号:命令替换,提取命令执行后的输出结果,`…`和$(…)作用相同
2)read命令
read命令获取输入内容
-p prompt:指定提示符,用于提示用户输入数据。
-a array:将输入数据存储到一个数组中。
方法一:
read -p "提示信息" 变量名
echo $变量名
方法二:
echo -n "提示信息"
read 变量名
echo $变量名
数组输入:
read -a
④ 设置变量的作用范围
默认情况下,新定义的变量只在当前的shell环境中有效,因此称为局部变量,当进入子程序或新的shell环境中,局部变量将无法再起作用。
可以通过内部命令export将指定的变量为全局变量,使用户定义的变量在所有子shell环境中可以继续使用
全局变量格式1: export 变量名
全局变量格式2:export 变量名=变量值
⑤ 数值变量的运算
1)整数变量的运算
格式:expr 变量1 运算符 变量2 [运算符 变量3]
运算符:+ 加法、- 减法、\* 乘法、/ 除法、% 取余
2)bc
bc是一个简单易用的计算器程序,可以用于执行基本的数学运算,
包括加、减、乘、除和取余等操作。
在Shell编程中,可以使用bc命令将数学表达式计算结果输出到标准输出或保存到文件中,以满足不同的需求。
3)非整数运算:
bash 不支持浮点运算,如果需要进行浮点运算,需要借助bc,awk 处理。
处理方式 | 加 | 减 | 乘 | 除 | 混合运算 |
bc | f=$(echo "4.3+2.5"|bc) echo "4.3+2.5=$f" | f=$(echo "4.3-2.5"|bc) echo "4.3-2.5=$f" | f=$(echo "4.30*2.50"|bc) echo "4.3*2.5=$f" | f=$(echo "scale=2;4.3/2.5"|bc) echo "4.3/2.5=$f" | f=$(echo "2.2/(2.2-1.1)*2+1.1"|bc) echo "2.2/(2.2-1.1)*2+1.1=$f" |
awk | f=$(awk 'BEGIN{print 4.5+3.4 }') echo "4.5+3.4=$f" | f=$(awk 'BEGIN{print 4.5-3.4 }') echo "4.5-3.4=$f" | f=$(awk 'BEGIN{print 4.5*3.4 }') echo "4.5*3.4=$f" | f=$(awk 'BEGIN{print 4.5/3.4 }') echo "4.5/3.4=$f" | f=$(awk 'BEGIN{print (4.5-3.4)*2+3 }') echo "(4.5-3.4)*2+3=$f" |
4)备注
变量名=$((表达式)) 等价于 变量名=$(expr 表达式) 等价于 变量名=$[表达式]
(3)特殊变量
① 环境变量
系统维护的变量,用于设置工作环境,使用env命令可以查看所有环境变量。
环境变量的全局配置文件为/etc/profile,在此文件中定义的变量作用于所有用户。
每个用户还有自己的独立配置文件(~/.bash_profile)。可以用来长期变更或设置某个环境变量。
用户级环境变量: 这些变量只对当前用户可见。每个用户可以定义自己的环境变量,用于满足个人需求。
例如,HOME变量指定了当前用户的主目录路径。
预定义环境变量: 操作系统或应用程序预先定义了一些常用的环境变量,用于提供特定的信息和功能。
例如,USER变量保存当前用户名,LANG变量指定了当前系统的默认语言。
自定义环境变量: 用户和应用程序可以定义自己的环境变量,用于存储特定的信息或配置。
这些变量可以根据需要随时创建、修改和删除。
$USER 表示用户名称
$HOME 表示用户的宿主目录
$LANG 表示语言和字符集
$PWD 表示当前所在工作目录
$PATH 表示可执行用户程序的默认路径
② 位置变量
通过命令行给脚本传递参数,主要指执行脚本时后面所跟着位置。
$1-$9:脚本后1-9的位置
${10}:脚本后10以上的位置需要借助变量分隔符{},不然会将$1认为是一个位置变量然后输出再加上后面的数字。
③ 预定义变量
系统已经定义好的变量:
$*:表示所有位置参数的内容看成一个整体返回
$@:表示输出脚本后的所有位置参数,且认为每个是独立的值
$0:表示当前执行的脚本或程序的名称 当前脚本的名字
$#:表示命令行中位置参数的总个数
$?:表示前一条命令执行后的返回状态,返回值为 0 表示上一条命令执行正确,返回任何非 0值均表示执行出现异常。使用方法echo $?
$!:后台任务最后一个id,使用方法echo $!
备注:
$*、$@不加双引号时表现一致;加双引号时,$*会将所有参数作为一个整体。
④ 只读变量:
只可以读取不能修改的变量,相当于常量,用处较少。
readonly 命令设置只读变量,只读变量不可以被重新赋值、不可以被删除,unset 命令用于删除变量。
二、实验
1.shell脚本实现位置变量运算
(1)进入脚本
(2) 将括号内num1与num2相加的执行结果赋值给变量sum
(3)执行脚本
2.Shell脚本实现read命令
(1)进入脚本
(2)编辑脚本
(3)执行脚本
3.Shell脚本实现if条件判断
(1)进入文件
(2)编辑文件
(3)执行脚本
数字相同
数字不同
4.Shell脚本实现浮点运算
进行浮点运算,需要借助bc,awk 处理。
加法:
减法:
乘法:
除法:
结果大于1
结果小于1
混合:
三、问题
1.Linux 执行命令为什么要加 ./(点斜杠)
(1)当前文件夹下有一个名为 first.sh 的 shell 脚本,但是在执行它的时候却提示找不到文件
(2)原因分析:
虽然终端是在当前目录,而且当前目录中有要执行的文件,但是终端就是找不到它。需要指定文件的相对或绝对路径来告诉终端我们想运行的文件在哪里。
在 Linux 中,点字符(.)表示工作目录,斜杠(/) 是 Linux 中的路径分隔符,用它来分离工作目录(.)与文件名。为什么需要 ./ ?因为我们的工作目录不包含在环境变量( $PATH )中。如果在路径名中存在 ./ 字符,那么就不搜索 $PATH。如果 ./ 不在路径名中,那么只在 $PATH 中搜索。
所以这就解释了为什么如果在 first.sh 前不加 ./ 就不能正常运行,原因就是在环境变量中没有名为 first.sh 的命令。$PATH:决定了shell将到哪些目录中寻找命令或程序,$PATH的值是一系列目录,当你运行一个程序时,Linux 在这些目录下进行搜索。
(3)输入命令 echo $PATH 查看当前的环境变量。
(4)在 Linux 上使用的命令都可以在这里面找到,例如ls 命令。但是如果我们想看命令具体的位置,可以使用 which 命令。
(5)在终端中输入:export PATH=$PATH:/data(这是一次临时的指定方法,关闭终端之后就不再生效:
(6)然后执行first.sh
2. $() 与 ${}区别
(1)$()是将括号内命令的执行结果赋值给变量
(2)${} 是用来作变量替换。一般情况下,$A 与 ${A} 并没有啥不一样。但是用 ${ } 会比较精确的界定变量名称的范围
3.cat 与echo区别
(1)cat
cat命令只是看文本文档文件的命令,二进制文件对于cat命令并不适用(二进制文件的查看通常是反编译或者使用strings命令查看二进制文件的某些细节);
cat命令并不适合查看大的文本文件,比如,超过200M大小的日志文件(tail -f 适合查询日志);
cat命令是Linux下的一个文本输出命令,通常是用于观看某个文件的内容的;
cat命令主要的应用在编辑,生成配置文件,查看配置文件,通过管道符 |grep 提取关键的有用信息,合并分片文件,以及在脚本内传递参数变量这些功能,由于管道符的配合加入,使得cat命令的应用极为灵活多变。
cat主要有三大功能:
① 一次显示整个文件。
cat filename
② 从键盘创建一个文件。
cat > filename
只能创建新文件,不能编辑已有文件.
③ 将几个文件合并为一个文件。
cat file file2 > file3
(2)echo (回显)
echo命令的功能是在显示器上显示一段文字,一般起到一个提示的作用。
echo 是一个专门输出自定义内容以及自定义和内置变量的值的命令,类似于Python、java这样的编程语言的内置函数print的简化版命令。
在Linux中,其实自定义内容也就是等于java的字符串,通常加单引号或者双引号,命令执行后返回字符串。在脚本编写进入调试阶段时,通常需要在脚本内echo特定内容以判定脚本是否执行正确。
4.期待操作数报错
解决方法:
运算符左右2侧均需要空格。
命令后跟参数
5.未预期的符号报错
解决方法:
变量名称前添加前导符号“$”,从而引用变量的值
6.未找到命令报错
解决方法:
条件判断用“==”,方括号[]内与调用变量间要有空格
7.bc运算
(1)减法结果显示不全
bc 作为强大而常用的计算工具,做减法运算时,如果结果值小于1,小数前面的 0 是缺失的:
解决方法:
%.1f表示保留到小数点后1位输出,补全0(%1f表示保留有效位数为1输出)
(2)除法结果显示不全(结果大于1)
bc 作为强大而常用的计算工具,做除法运算时,如果结果值大于1,小数后面是缺失的,小数位后显示不全:
解决方法:
scale保留运算结果到小数点后2位
(3)(结果小于1)
除法结果显示不全
bc 作为强大而常用的计算工具,做除法运算时,如果结果值小于1,小数前面的 0 是缺失的,小数位前显示不全:
解决方法:
%.2f表示保留到小数点后2位输出,补全0
scale保留运算结果到小数点后2位