shell编程规范与变量

427 阅读8分钟

shell脚本概述

shell脚本的概念:

  1. 将要执行的命令按顺序保存到一个文本文件
  2. 给该文件可执行权限
  3. 可结合各种shell控制语句以完成更复杂的操作

shell脚本应用场景:

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

shell的作用——命令解释器,“翻译官”

介于系统内核与用户之间,负责解释命令行

在用户和内核之间充当“命令翻译官”

Snipaste_2022-08-23_18-44-05.png

Linux中有哪些shell

/etc/shells 文件里包含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

Snipaste_2022-08-23_18-46-00.png

扩展:

为什么系统上合法的shell要写入/etc/shells这个文件呢?

这是因为系统某些服务运行过程中,会去检查用户能够使用的Shell,而这些shell的查询就是借由/etc/shells这个文件

用户什么时候可以取得shell来工作?用户默认会取得哪一个shell?

当用户登录的时候,系统就会给我一个shell让我来用,而这个登录取得的Shell就记录在/etc/passwd这个文件内

shell脚本的作用

  • 自动化运维
  • 批量化重复操作可以编写脚本结合计划任务自动周期运行
  • 减轻管理员工作量
  • 提高处理文本文件的速度
  • 避免配置出错

扩展:

shell是一个面向字符串的编程语言,可以跟python之类的其他语言配合起来,比如某个复杂的功能使用一个python脚本来实现,然后在shell中调用这个脚本实现比较复杂的功能,或者反过来,在python脚本中调用外部的shell脚本来提高自动化的效率,也是可以的

shell 可针对 linux系统做自动化运维和状态监控

python 可针对通过API接口对应用程序做数据的收集、统计和分析

编程语言分强类型和弱类型

强类型:int string C c++ java GO

弱类型:shell python 解释性语言

shell编程规范

编写脚本代码

使用vi或vim编辑器,一般都是使用vim编辑器

每行一条linux命令,按执行顺序一次编写

shell脚本的构成

脚本申明(解释器):若第一行为“#!/bin/bash”,表示此行以下的代码语句是通过/bin/bash程序来解释执行,#!/bin/bash为默认解释器,还有其他类型的解释器,比如#!/uer/bin/python 、#!/usr/bin/expect

注释信息:以“#”开头的语句表示为注释信息,被注释的语句在运行脚本时不会被执行(shell脚本文件的第一行是例外,#后面的!会告诉shell用哪个shell来运行脚本)

可执行语句:比如echo命令,用于输出“ ”之间的字符串

构成:

shell 脚本代码 申明解释器 #!/bin/bash 或 省略

python 代码 必须申明解释器 #!/usr/bin/pyhton 或 #!+ python执行文件的其他路径

创建shell脚本

#!/bin/bash 申明解释器

#xxxxxx 做脚本的注释信息

..... 代码块

#! /bin/bash                          #脚本解释器声明
# This is my first Shell-Script.      #注释,在写脚本时要加注释,一般是一半脚本一半注释,注释内容最好使用英文,因为中文模式容易导致代码出现错误
cd /boot
echo "当前的目录位于:"
pwd
echo "其中以vml开头的文件包括: "
ls -lh vml*

Snipaste_2022-08-23_18-49-59.png

运行shell脚本:

会在脚本的子shell环境执行shell脚本中的代码

使用绝对路径或相对路径指定脚本的路径运行,要求脚本文件必须要有执行权限x

Snipaste_2022-08-23_18-53-34.png

指定shell程序来直接解释运行脚本

bash 脚本文件

sh 脚本文件

会在当前的shell环境中执行脚本里的代码操作,也就是脚本文件中的代码或者命令会影响当前的环境

source 脚本文件

. 脚本文件

管道操作

将管道符号“|”左侧的命令输出的结果,作为右侧命令的输入(处理对象),同一行命令中可以使用多个管道

例子:
ps aux | wc -l   ##查看进程数
echo "abc123" | passwd --stdin  zhangsan   ##给zhangsan用户设置密码abc123

xxx | 如果管道符右边是一定需要执行对象的命令,则管道符号后面要有xargs命令来传递执行参数

重定向

交互式硬件设备:

标准输入:从该设备接收用户输入的数据

标准输出:通过该设备向用户输出数据

标准错误:通过该设备报告执行出错信息

类型设备文件文件描述编号默认设备
标准输入/dev/stdin0键盘
标准输出/dev/stdout1显示器
标准错误输出/dev/stderr2显示器

重定向操作

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

例子:

重定向输出和输入

需要注意setenforce 会影响此命令执行,若执行失败可尝试关闭setenforce

Snipaste_2022-08-23_19-27-37.png

标准错误输出:

Snipaste_2022-08-23_22-57-45.png

shell变量的作用、类型

变量的作用

用来存放系统和用户需要使用特定参数(值)

变量名:使用固定的名称,由系统预设或用户定义

变量值:能够根据用户设置、系统环境的变化而变化

变量的类型

  • 自定义变量:由用户自己定义、修改和使用

  • 特殊变量:环境变量、只读变量、位置变量、预定义变量

    环境变量: 由系统维护,用于设置工作环境
    
    位置变量: 通过命令行给脚本程序传递参数
    
    预定义变量: Bash中内置的一类变量,不能直接修改
    

自定义变量

定义一个新的变量

变量名以字母或下划线开头,区分大小写,建议全大写

变量名=变量值

查看变量值

echo $变量名

Snipaste_2022-08-23_18-58-29.png

变量名出现空格,使用“ ”号

出现特殊字符串,使用 { } 括起来

赋值时使用引导

双引号 " " :允许通过$符号引用其他变量值

单引号 ' ' :禁止引用其他变量值,$视为普通字符

双撇号 `` :命令替换,提取命令执行后的输出结果 和 $( ) 效果一样

Snipaste_2022-08-23_23-01-58.png

read 获取标注输入的内容给变量

方法一:
read -p “提示信息” 变量名
 
方法二:
#!/bin/bash
echo -n "提示信息:"
read 变量名
echo $变量名

Snipaste_2022-08-23_19-45-07.png

Snipaste_2022-08-23_19-48-29.png

变量作用范围

局部变量和全局变量

默认情况下,新定义的变量只在当前的shell环境中有效,因此称为局部变量。当进入子程序或新的子Shell环境时,局部变量将无法再使用

可以通过内部命令export将指定的变量导出为全局变量,使用户定义的变量在所有的子Shell环境中能够继续使用

设置全局变量格式:

格式1: export 变量名
格式2: export 变量名=变量值
Snipaste_2022-08-23_19-56-42.png

整数变量的运算:

格式:

expr 变量1 运算符 变量2 [运算符 变量3]

常用运算符:

加法运算:+

减法运算:-

乘法运算:**\ ***

除法运算:/

取余运算:%

shell默认只支持整数运算

整数运算:
1.expr 数值或变量  运算符  数值或变量
2.echo $[数值  运算符 数值]
3.echo $((数值 运算符 数值))
4.let 变量名=<数值><运算符><数值>
  echo $变量名
  let i++   是先赋值 再加一 相当于i=$[$i+1]
  let i--   是先赋值 再减一 相当于i=$[$i-1]
  let i+=n  在赋值的基础上加n 相当于i=$[$i+2]
​
浮点(小数点)运算
echo "sacle=2;浮点运算表达式 " |bc   sacle:结果后面有几位数
awk 'BEGIN{print 浮点运算表达式}'  最多保留5个小数位
举例:

echo $((10/5))

Snipaste_2022-08-23_19-01-44.png

echo $[5*5]

Snipaste_2022-08-23_19-01-51.png

let 变量名=<数值><运算符><数值>

Snipaste_2022-08-23_19-02-13.png

特殊的shell变量

环境变量

环境变量由系统提前创建,用来设置用户的工作环境

使用env命令可以查看到当前工作环境下的环境变量

变量USER表示用户名称,HOME表示用户的宿主目录,LANG表示语言和字符集,PWD表示当前所在的工作目录

变量PATH表示可执行程序的默认搜索路径

设置系统根据环境变量自动设置可执行程序

echo $PATH                  #查看当前搜索路径
PATH="$PATH:/root"          #将/root目录添加到搜索路径
export PATH="$PATH:/root"   #输出为全局环境变量
​
设置永久有效:
echo 'export PATH=$PATH:/root' >> /etc/profile            #将全局环境变量追加到/etc/profile配置文件中

Snipaste_2022-08-23_23-09-55.png

环境变量配置文件为:

/etc/profile,定义的变量作用于所有用户

~/.bash_profile 用户独立的配置文件,修改此文件只作用于当前用户

只读变量

readonly 命令用于定义只读shell变量和shell函数

readonly 【选项】【参数】
​
name=lili
readonly name        #设置为只读变量
echo $name
name=zhansan           #只读变量不可以被重新赋值unset name         #只读变量不可以被删除,unset命令用于删除变量

位置变量

当执行命令行操作时,第一个字段表示命令名或脚本程序名,其余的字符串参数按照从左到右的顺序依次赋值给位置变量。

n:n为数字,n: n为数字,0代表命令本身,11- 9代表带一个到第九个参数,十以上的参数需要使用大括号表示,比如第十个参数为${10}

Snipaste_2022-08-23_23-14-27.png

预定义 变量

$0 :代表脚本本身

* 、@:都会表示脚本后面跟的所有参数

  • "":把所有参数看成一个字符串整体(单字符串)返回,代表"*" :把所有参数看成一个字符串整体(单字符串)返回,代表"1 22 3 $4 "
  • "@":把所有参数加上空格分隔成n份的参数个体,每个参数作为一个字符串返回,代表“@":把所有参数加上空格分隔成n份的参数个体,每个参数作为一个字符串返回,代表“1” “2”“2” “3” “$4”

$#:表示命令行中脚本后面参数的总个数

$?:表示前一条命令执行后的返回状态码,返回值为0表示执行正确,返回任何非0值表示执行出现异常

**实操:

$* $# $@的用法

Snipaste_2022-08-23_20-24-46.png

"$*" "$@"的用法

Snipaste_2022-08-23_20-29-15.png

Snipaste_2022-08-23_20-31-09.png

$?的使用

Snipaste_2022-08-23_20-33-05.png