Shell编程规范与变量

235 阅读7分钟

前言

Shell就是一个命令行解释器,它的作用就是遵循一定的语法将输入的命令加以解释并传给系统。它为用户提供了一个向Linux发送请求以便运行程序的接口系统级程序,用户可以用Shell来启动、挂起、停止甚至是编写一些程序。 Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言(就是你所说的shell脚本)。作为命令语言,它互动式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高阶语言中才具有的控制结构,包括循环和分支。它虽然不是 Linux系统内核的一部分,但它调用了系统内核的大部分功能来执行程序、创建文档并以并行的方式协调各个程序的运行。

shell概念

shell脚本就是由Shell命令组成的执行文件,将一些命令整合到一个文件中,进行处理业务逻辑,脚本不用编译即可运行。 它通过解释器解释运行,所以速度相对来说比较慢。 shell脚本中最重要的就是对shell命令的使用与组合,再使用shell脚本支持的一些语言特性,完成想要的功能。 局部变量:局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
本机shell: Snipaste_2022-08-28_17-18-04.png

Shell脚本应用场景

用途

  • 自动化常用命令
  • 执行系统管理和故障排除
  • 创建简单的应用程序
  • 处理文本或文件

应用场景

  • 重复性操作
  • 交互性任务
  • 批量事务处理
  • 服务运行状态监控
  • 定时任务执行

shell的作用

  1. Shell的作用——命令解释器,“翻译官”介于系统内核与用户之间,负责解释命令行
  2. 用户的登录Shell登录后默认使用的Shell程序,一般为/bin/bash不同Shell的内部指令、运行环境等会有所区别

shell编辑及构成

打开文本编辑器(可以使用vi/vim命令来创建文件),新建一个文件test.sh,扩展名为sh(sh代表shell),扩展名并不影响脚本执行

  1. 脚本申明(解释器)﹔若第一行为"#!/bin/bash",表示此行以下的代码语句是通过/bin/bash程序来解释执行,#!./bin/bash为默认解释器。还有其它类型的解释器,比如# !/usr/bin/python、# !/usr/bin/expect。
  2. 注释信息:以"#”开头的语句表示为注释信息,被注释的语句在运行脚本时不会被执行。
  3. 可执行语句:比如lecho命令,用于输出”"之间的字符串。

Snipaste_2022-08-28_17-38-37.png

脚本的执行方式

  1. 指定路径去执行文件,文件需要有执行权限

Snipaste_2022-08-28_17-53-24.png

  1. 指定解释器去执行(bash 脚本名),不需要执行权限
  • sh命令 sh脚本路径: sh first.sh

  • source命令也称为“点命令”,也就是一个点符号(.),是bash的内部命令不需要x权限,也需要使用相对路径或绝对路径。 source脚本路径:. first.sh或者source first.sh(使用当前shell环境执行脚本文件,目录发生变化)

Snipaste_2022-08-28_17-57-01.png

执行脚本时的shell环境:
source和 . 执行脚本时,会在当前shell环境中执行脚本。
bash、绝对路径、相对路径 执行脚本时,会创建一个子shell环境,并在这个子shell环境中执行脚本。
不建议使用source来执行脚本,可能会影响一些资源配置。

重定向与管道符

由于Shell脚本“批量处理”的特殊性,其大部分操作过程位于后台,不需要用户进行干预,因此要学会提取、过滤执行信息变得十分重要,所以我们需要重定向和管道。
交互式硬件设备

  • 标准输入:从该设备接收用户输入的数据
  • 标准输出:通过该设备向用户输出数据
  • 标准错误:通过该设备报告执行出错信息
类型设备文件文件描述编号默认设备
标准输入/dev/stdin0键盘
标准输出/dev/stdout1显示器
标准错误输出/dev/stderr2显示器

重定向:不通过标准输出到默认屏幕上,而是输出到你指定的位置

类型操作符用途
重定向输入<从指定的文件读取数据
重定向输出>将标准输出结果保存到指定的文件,并且覆盖原有内容
重定向输出>>将标准输出结果追加到指定的文件的尾部,不覆盖原有内容
标准错误输出2>将错误信息保存到指定的文件,并且覆盖原有内容
标准错误输出2>>将错误信息追加到指定的文件的尾部,不覆盖原有内容
混合输出&>将标准输出、标准错误保存到同一文件中
混合输出2>&1将标准错误输出重定向到标准输出

Snipaste_2022-08-28_19-05-13.png 管道符
将管道符号"I"左侧的命令输出的结果,作为右侧命令的输入(处理对象),同一行命令中可以使用多个管道符。
格式:
命令A | 命令B

Snipaste_2022-08-28_19-00-23.png 如果管道符合右边是一定需要执行对象的命令,则管道符号 后面要有 xargs 命令来传递执行参数。

变量

变量即在程序运行过程中它的值是允许改变的量。

变量的作用

用来存放系统和用户需要使用的特定参数(值)
变量名:使用固定的名称,由系统预设或用户定义
变量值:能够根据用户设置、系统环境的变化而变化

变量的分类

根据变量的生效范围可分为:

  • 环境变量(全局变量):全局生效,在任何bash环境中都可以识别。
  • 局部变量:生效范围为当前shell进程。对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效。
  • 本地变量:生效范围为当前shell进程中某代码片断,通常指函数。 只能在定义它们的函数/脚本内部中使用。

根据是否由系统定义可分为:

  • 内置变量:由系统维护,用于设置工作环境。如PS1,PATH,HISTSIZE, HOSTNAME,USER。
  • 自定义变量:由用户自己定义、修改和使用。

自定义变量

定义变量格式:
变量名=变量值
变量命名规则:以字母或下划线开头,区分大小写
等号(=)用来给变量赋值
查看变量值格式:
echo $变量名

Snipaste_2022-08-28_19-45-36.png 删除变量格式:
unset 变量名

Snipaste_2022-08-28_21-12-59.png 赋值时使用符号

  • 双引号:允许通过$符号引用其他变量值
  • 单引号:禁止引用其他变量值, $视为普通字符
  • 反撇号:命令替换,提取命令执行后的输出结果,``和$(…)作用相同
  • 大括号:定义变量范围

Snipaste_2022-08-28_19-56-45.png

从键盘输入内容为键盘赋值

read命令获取输入内容
read [-p “提示信息”]变量名
echo $变量名

read 常用选项

  • -p:后面跟提示信息,即在输入前打印提示信息。
  • -s:安静模式,在输入字符时不再屏幕上显示,例如密码。
  • -t:后面跟秒数,定义输入字符的等待时间。
  • -n:后跟一个数字,定义输入文本的长度。
  • -a:后跟一个变量,该变量会被认为是个数组。 Snipaste_2022-08-28_20-06-39.png vim 自定义变量名.sh
    echo $变量名

Snipaste_2022-08-28_20-09-49.png

Snipaste_2022-08-28_20-10-05.png

设置全局变量

可以使用pstree命令查看shell环境,输入bash命令进入子shell环境,
按ctrl+D组合键或输入exit命令退出子shell环境export product version
pstree查看界面 Snipaste_2022-08-28_20-19-13.png

Snipaste_2022-08-28_20-20-16.png

默认情况下,新定义的变量只在当前的shell环境中有效,因此称为局部变量,当进入子程序或新的shell环境中,局部变量将无法再起作用。
可以通过内部命令export将指定的变量为全局变量(即环境变量),使用户定义的变量在所有子shell环境中可以继续使用。
格式:export 变量名 Snipaste_2022-08-28_19-28-51.png

环境变量

  1. 内置环境变量
  • 由系统提前创建,用来设置用户的工作环境
  • 使用env命令查看所有环境变量: Snipaste_2022-08-28_20-32-30.png 常用环境变量:
  • $PATH 表示可执行文件的默认路径
  • $USER 表示用户名称
  • $HOME 表示用户的宿主目录
  • $LANG 表示语言和字符集
  • $PWD 表示当前所在工作目录
  1. 配置文件 自定义的环境变量只是临时生效,退出系统后就会失效。需要将自定义的环境变量放入配置文件中,才会永久生效。配置文件可以用来长期变更或设置环境变量。 配置文件:/etc/profile(全局生效)、~/.bash_profile(当前用户环境)

只读变量

用于变量值不允许被修改的情况

  • 第一步:A=B 定义一个变量
  • 第二步:readonly A 使用 readonly 来修饰该变量 ,表明只读 Snipaste_2022-08-28_20-43-35.png

位置变量

位置变量也称为位置参数。

使用$n表示,n为数字序列号,且必须为整数。两位数需要加大括号{},不然$10会被识别为:$1和0 。$1,$2..$9,${10},${11}

Snipaste_2022-08-28_20-51-58.png

Snipaste_2022-08-28_20-51-45.png

预定义变量

预定义变量是系统定义好的变量,用来保持脚本程序的执行信息。可以直接使用这些变量,不能直接为这些变量赋值。

$0当前脚本名称(如果是软链接,显示当前软链接文件名)
$?查看上一次命令的执行状态,返回0为正常,非0为错误
$*把所有参数看成以空格分隔的一个字符串整体,代表"$1`` $2 $3 $4"
$@把各个参数加上双引号分隔成n份的参数列表,每个参数是独立 的,代表"$1" “$2” “$3” “$4
$#获取当前shell命令行中参数的总个数
$_在此之前执行的命令或脚本的最后一个参数
$$获取当前进程的PID

Snipaste_2022-08-28_21-01-37.png

Snipaste_2022-08-28_21-05-56.png Snipaste_2022-08-28_21-05-23.png

变量算术运算

默认情况下bash只支持整数运算,不支持小数运算
整数变量的算术运算

算法运算符运算法则
加法+A+B
减法-A-B
乘法*A * B
整除/A/B
取余%A%B

expr命令是一个手工命令行计数器,一般用于整数值,也可用于字符串 Snipaste_2022-08-28_21-37-35.png Snipaste_2022-08-28_21-39-00.png Snipaste_2022-08-28_21-41-49.png

let(())也都用于算数运算。两者都不返回结果,需要借助echo命令

Snipaste_2022-08-28_21-56-06.png 变量自增与自减
i++ 相当于 i=[[i+1]
i-- 相当于 i=[[i-1]
i+=2 相当于 i=[[i+2]

Snipaste_2022-08-28_22-24-52.png

比较 i++ 和 ++i:
i++ 是先赋值再自增; ++i 是自增后再赋值

Snipaste_2022-08-28_22-27-23.png $[]$(())也都支持对变量进行运算。效果相同

Snipaste_2022-08-28_22-01-00.png

小数运算(浮点运算)

bash 不支持浮点运算,如果需要进行浮点运算,需要借助bc, awk处理
bc运算:echo "算术表达式" | bc

Snipaste_2022-08-28_22-14-09.png

awk进行浮点数的运算,运算结果最多显示6个有效数字
awk运算:awk "BEGIN{print 算术表达式}"

Snipaste_2022-08-28_22-18-14.png