自动化运维必须要学的Shell脚本之——编程规范和变量详细解读
Posted 码海小虾米_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自动化运维必须要学的Shell脚本之——编程规范和变量详细解读相关的知识,希望对你有一定的参考价值。
Shell变成规范与变量
一、Shell脚本概述
1.1 Shell的作用
1.Shell脚本的概念
- 将要执行的命令按顺序保存到一个文本文件;
- 给该文件可执行权限;
- 可结合各种Shell控制语句以完成更复杂的操作。
2.Shell脚本的应用场景
- 重复性操作
- 交互性任务
- 批量事务处理
- 服务运行状态监控
- 定时任务执行
3.Shell的作用 — 命令解释器,充当“翻译官”
介于系统内核与用户之间,负责解释命令行,Shell (壳程序)是一个特殊的应用程序,它介于操作系统内核与用户之间,充当了一个“命令解释器"的角色,负责接收用户输入的操作指令(命令)并进行解释,将需要执行的操作传递给内核执行,并输出执行结果。
4.Linux中有哪些Shell
最常用的就是bash、tcsh、 csh、sh、 nologin这些shell。这些shell都是依据Linux发展者的不同所创造出的不同版本。
- bash:基准于GNU的框架下发展出的Shell。
- csh: 语法有点类似于c语言的Shell。
- tcsh:整合了csh,提供更多的功能。
- sh:已经被bash所替换。
- nologin: 奇怪的shell,这个shell可以让用户无法登录主机。
注: bash ( /bin/bash) 是目前大多数Linux版本采用的默认Shell。
5.补充内容
- 为什么系统上合法的Shell要写入/etc/ shells这个文件呢?
这是因为系统某些服务运行过程中,会去检查用户能够使用的Shell,而这些shell的查询就是借由/etc/shells这个文件。 - 用户什么时候可以取得shell来工作?用户默认会取得哪一个shell?
当用户登录的时候,系统就会给我一个shell让我来用,而这个登录取得的Shell就记录在/etc/passwd这个文件内
1.2 Shell编程规范
1.编写脚本代码
- 使用vi或者vim编辑器,一般都是使用vim编辑器
- 每行一条Linux命令,按执行顺序一次编写
vim /root/first.sh #使用vim编辑器
#!/bin/bash #脚本解释器声明
# this is my first shell-script #注释
echo 当前目录位于: #linux命令
pwd #linux命令
2.shell脚本的构成
- 脚本申明(解释器) :若第一行为“#!/bin/bash", 表示此行以下的代码语句是通过/bin/bash程序来解释执行,#!/bin/bash为默认解释器。还有其它类型的解释器,比如#!/usr/bin/python、#!/usr/bin/ expect。
- 注释信息:以“#”开头的语句表示为注释信息,被注释的语句在运行脚本时不会被执行。(shell脚本文件的第一行是个例外,#后面的感叹号会告诉shell用哪个shell来运行脚本)
- 可执行语句:比如echo命令,用于输出" "之间的字符串。
- 可使用unset进行对变量的取消:
3.shell脚本的执行
1)方法一:指定路径的命令,要求文件必须有 x(可执行)权限。
chmod +x /root/first.sh #给脚本添加可执行权限
指定绝对路径: /root/first.sh
指定相对路径: ./first.sh
2)方法二:指定shell来解释脚本,不要求文件必须有 x (可执行)权限。
sh 脚本路径: sh first.sh
source 脚本路径:. first.sh 或者 source first.sh(会切换到)
实例:sh 脚本路径执行shell脚本
实例:source 脚本路径执行shell脚本
4.shell脚本显示消息
大多数shell命令都会产生自己的输出,这些输出会显示在脚本所运行的控制台显示器上,很多时候,我们需要添加自己的文本消息来告诉执行脚本的用户当前脚本正在做什么。可以通过echo命令来实现这一点,如果在echo命令后面加上一个字符串,该命令就能显示出这个文本字符串。
默认情况下,不需要使用引号就可以将要显示的文本字符串显示出来,但是有时在字符串中出现引号的话就会出现问题了。echo命令可用单引号或者双引号来划定文本字符串,如果在字符串中用到了他们,我们需要在文本中使用其中一种引号,而用另一种来将字符串划定起来。
如果想要把文本字符串和命令输出显示在同一行中,可以使用echo语句的 -n
参数。
1.3 重定向与管道
1.由于Shell脚本“批量处理”的特殊性,其大部分操作过程位于后台,不需要用户进行干预,因此要学会提取、过滤执行信息变得十分重要,所以我们需要重定向和管道。
将管道符号“|”左侧的命令输出的结果,作为右侧命令的输入(处理对象),同- -行命令中可以使用多个管道。
ps aux | wc -l #查看进程数
echo "abc123" | passwd --stdin zhangsan #给zhangsan用户设置密码abc123
交互式硬件设备 | 设备文件 | 文件描述编号 | 默认设备 |
---|---|---|---|
标准输入 | /dev/stdin | 0 | 键盘 |
标准输出 | /dev/stdout | 1 | 显示器 |
标准错误输出 | /dev/stderr | 2 | 显示器 |
重定向的操作
实例:将123456重定向输出到pass.txt文件中,然后将pass.txt的内容重定向输入给用户张三的密码
注意:从pass.txt 文件中取密码,需要注意SELinux 会影响此命令执行,若执行失败可尝试关闭SELinux(setenforce 0)。
实例:实验混合输出
本来1—>屏幕 ( 1指向屏幕)
执行>log后,1–>1og.txt (1指向log. txt)
执行2>&1后,2–>1 (2指向1,而1指向log. txt,因此2也指向了log. txt)
实例:输入重定向,显示passwd中的行数,单词数和字节数。
二、Shell脚本变量
2.1 shell变量的作用、类型
2.1.1 变量的作用
- 用来存放系统和用户需要使用的特定参数(值)
- 变量名:使用固定的名称,由系统预设或用户定义
- 变量值:能够根据用户设置、系统环境的变化而变化
2.1.2 变量的类型
- 自定义变量:由用户自己定义、修改和使用;
- 特殊变量:环境变量,只读变量,位置变量,预定义变量。
2.1.3 自定义变量
1.定义新的变量:
变量名以字母或者下划线开头,区分大小写,建议全大写,长度不超过20个。
变量名=变量值
2.查看变量的值:
echo $变量名
实例:自定义变量可修改,引用时。都会输出最新赋予的值
3.赋值时使用引号
- 双引号:允许通过$符号引用其他变量值
- 单引号:禁止引用其他变量值,$视为普通字符
- 反撇号:命令替换,提取命令执行后的输出结果
testing=`date` , 也可以是testing$(date) ,代表的意思相同
实例:使用反撇号赋给变量,然后使用$使用该变量
实例:通过命令替换获得当前日期并使用它来创建唯一的文件名。
2.1.4 read命令获取用户输入的内容
方法一:
read -p “提示信息” 变量名
方法二:
#!/bin/bash
echo -n "提示信息:"
read 变量名
实例:方法一获取用户输入的信息
实例:方法二获取用户输入的信息
2.2 变量作用范围
2.2.1 局部变量和全局变量
默认情况下,新定义的变量只在当前的Shell环境中有效,因此称为局部变量。当进入子程序或新的子Shell环境时局部变量将无法再使用。
可以通过内部命令export将指定的变量导出为全局变量,使用户定义的变量在所有的子Shell环境中能够继续使用。
格式1: export变量名
格式2: export 变量名=变量值
实例:测试局部变量和全局变量
2.2.2 shell环境
可以使用pstree 命令查看Shell环境,输入bash命令进入子Shell环境
按Ctrl+D组合键或输入exit命令退出子Shell环境
2.3 整数变量的运算
- 格式:
expr 变量1 运算符 变量2 [运算符 变量3]
- 运算符:
+ 加法、-减法、\\*乘法、/除法、%取余
- 常见的运算表达式:(result代表自定义变量,可用任意代替)
- result=$(expr 变量1 运算符 变量2)
- result=$((变量1 运算符 变量2))
- result=$[变量1 运算符 变量2]
- let result=变量1 运算符 变量2
- 常用的运算表达式:(下列举例中:a=10,b=20)
-
数字运算:
i=$(expr 12\\*5)
变量运算:i=$(expr $a \\* $b)
-
数字运算:
i=$((12 * 5))
变量运算:i=$(($a * $b))
-
数字运算:
i=$[12 * 5]
变量运算:i=$[$a * $b]
-
数字运算:
let i=10 * 10
变量运算:let i=$a*$b
-
i++
相当于i=$[$i + 1]
-
i--
相当于i=$[$i - 1]
-
i+=1
相当于i=$[$i + 1]
-
2.4 环境变量
1.环境变量由系统提前创建,用来设置用户的工作环境,使用env命令
可以查看到当前工作环境下的环境变量:
- 变量
USER
表示用户名称 HOME
表示用户的宿主目录LANG
表示语言和字符集PWD
表示当前所在的工作目录- 变量
PATH
表示可执行程序的默认搜索路径
使用echo命令
进行查看环境变量:
2.设置系统根据环境变量自动设置可执行程序。
echo $PATH #查看当前搜索路径
PATH="$PATH:/root" #将/root目录添加到搜索路径
export PATH="$PATH:/root" #输出为全局环境变量
设置永久有效:
echo 'export PATH=$PATH:/root' >> /etc/profile #将全局环境变量追加到/etc/profile中
实例:将test脚本的所在目录加入搜索路径,然后测试直接执行脚本
2.5 只读变量
readonly
命令用于定义只读shell变量和shell函数。readonly
命令的选项-p
可以输出显示系统中所有定义的只读变量。
格式:readonly 【选项】【参数】
2.6 位置变量
- 当执行命令行操作时,第一个字段表示命令名或脚本程序名,其余的字符串参数按照从左到右的顺序依次赋值给位置变量。
- $n: n为数字,$0代表命令本身,$1- $9代表带一个到第九个参数,十以上的参数需要使用大括号表示,比如第十个参数为${10}
实例:测试$10不加大括号和加大括号的区别
加上大括号之后如下:
实例:使用位置变量进行编写shell脚本的加法运算
2.7 预定义变量
1.$* 和 $@:都会表示命令或脚本要处理的参数。
- $* :把所有参数看成以空格分隔的一个字符串整体(单字符串)返回,代表"$1 $2 $3 $4 "
- $@:把各个参数加上双引号分隔成n份的参数列表,每个参数作为一个字符串返回,代表“$1” “$2” “$3” “$4”
预定义变量 | 表示的意思 |
---|---|
$0 | 表示当前执行的脚本或命令的名称 |
$# | 表示命令或者脚本要处理的参数的个数 |
$? | 表示前一条命令或脚本执行后的返回状态码,返回值为0表示执行正确,返回任何非0值均表示执行出现异常,也常被用于shell脚本中return退出函数并返回的退储值 |
实例:$* 和 $#的使用和区别
$* 和 $#的使用:
$* 和 $#的区别:上面例子还是看不出来有什么区别的,我们需要借助for循环来查看具体的区别。
实例:$?的使用,可用来判断服务状态是否正常。
案例:编写脚本,压缩文件的时候自动显示填写压缩文件名(包含当天日期),而且自定义压缩后显示的信息。
2.8 浮点数运算
bash不支持浮点数运算(小数运算),如果需要进行浮点数运算,则需要bc、awk的帮助。
2.8.1 bc的基本用法
bash计算器实际上是一种编程语言,它允许在命令行中输入浮点表达式,然后解释并计算该表达式,最后返回结果。bash计算器能够识别:
- 数字(整数和浮点数)
- 变量(简单变量和数组)
- 注释(以#或C语言中的/* */开始的行)
- 表达式
- 编程语句(例如if-then语句)
- 函数
1.第一种用法:直接使用bc,然后像使用计算器一样使用(-q选项可以不显示bash计算机的欢迎信息)
浮点允许是由内建变量scale控制的,必须将这个值设置为你希望在计算结果中保留的小数位数,否则无法得到想要的结果,如下例子:
scale变量的默认值是0,在scale值被设置前,bash计算器的计算结果不包括小数位,在设置为4后,显示的结果包含四位小数。
除了数字外,bash计算器还能支持变量
1.第二种用法:在脚本中使用
如下列案例:用命令替换运行bc计算器,然后设置scale=4,然后将结果赋予给变量var1,然后输出结果。
2.8.2 awk的基本用法
以上是关于自动化运维必须要学的Shell脚本之——编程规范和变量详细解读的主要内容,如果未能解决你的问题,请参考以下文章
自动化运维必须要学的Shell脚本之——数组(冒泡排序和反转排序等)
自动化运维必须要学的Shell脚本之——循环语句(forwhile和until循环)