shell编程规范与变量

shell脚本基础

1.shell概述

shell脚本的概念

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

shell应用应用场景

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

shell的作用

Linux系统中的shell是一个特殊的应用程序,它介于操作系统内核与用户之间,充当了一个“命令解释器”的角色,负责接收用户输入的操作指令(命令)并进行解释,将需要执行的操作传递给内核执行,并输出执行结果。

2.用户的登录shell

常见的shell解释器程序有很多种,使用不同的shell时,其内部指令、命令行提示符等方面会存在一些区别。通过/etc/shells文件可以了解当前系统所支持的shell脚本种类。

  • 登录后默认使用的shell程序,一般为/bin/bash
点击查看代码
[root@node1 ~]#  cat /etc/shells   //查看当前的系统支持的shell
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh

linux中常见的shell:

  • bsah:基于gun的框架下发展的shell
  • csh:类似c语言的shell
  • tcsh:整合了csh提供了更多功能
  • sh:已经被bash替换
  • nolongin:让用户无法登录

3.shell脚本的构成

  • 脚本申明(申明解释器):第一行开头“#!/bin/bash”,表示此行以下的代码语句是通过/bin/bash程序来执行的。还有其他类型的解释器,比如#/usr/bin/python、#!/usr/bin/expect(免交互)。
  • 注释信息:以“#”开头的语句表示为注释信息,被注释的雨具在脚本运行时不会被执行
  • 可执行语句:如echo命令,用于输出“”之间的字符串。
点击查看代码
例:
#!/bin/bash          //解释器
#this is test        //注释
echo "hello world"   //执行的命令

4.脚本执行逻辑及执行方式
脚本执行逻辑:

  • 顺序执行:程序按从上到下顺序执行
  • 选择执行:程序执行过程中,根据条件的不同,进行选择不同分支继续执行
  • 循环执行:程序执行过程中需要重复执行多次某段语句

脚本执行方式:

  • 1直接使用shell程序来读取脚本中的命令,不需要执行权限
点击查看代码
`bash 脚本名`

[root@node1 ~]#  bash test.sh       //执行脚本
this is test

- 2使用路径执行,需要权限
点击查看代码
`绝对路径。如:/~/test.sh`
`相对路径。如:./test.sh`

[root@node1 ~]#  chmod +x test.sh   //添加执行权限
[root@node1 ~]#  ~/test.sh          //绝对路径执行脚本
this is test 

[root@node1 ~]#  ./test.sh          //相对路径执行脚本
this is test

  • 3使用“source脚本名”或“.脚本名”执行脚本,不需要权限
    1和2执行方式不会影响当前环境中bash设置,会开启一个全新的bash环境执行脚本
    3不推荐使用,不会启动子shell环境,会影响当前bash环境中的配置

5.常见脚本错误

脚本错误类型:

  • 命令错误:命令错误不会影响接下来的命令继续执行。
  • 语法错误:会导致后续的命令不执行。造成脚本中一部分命令已执行,一部分未执行
  • 逻辑错误:执行后的效果不是自己想要的。需要自行排查

调试方法:

点击查看代码
命令错误调试:
在脚本的前面输入 `set -e` ,一旦出错立即停止

bash -n 脚本名称     //只检查语法错误,不真正执行脚本。定位的错误行可能不准确。

bash -x 脚本名称     //显示每个命令的执行过程,方便发现逻辑错误

重定向与管道符

1.标准输入、输出

当执行shell命令时,会默认打开3个文件,每个文件有对应的文件描述符来方便我们使用:

  • 标准输入:从该设备接收用户输入的数据
  • 标准输出:通过该设备向用户输出数据
  • 标准错误:通过该设备报告执行出错信息
类型 设备文件 文件描述编号
标准输入 /dev/stdin 0
标准输出 /dev/stdout 1
标准错误输出 /dev/stderr 2

重定向

重定向的意思就是,不输出到默认设备上,输出到你指定的位置(文件、其他输出设备)

类型 操作符 用途
重定向输入 < 从指定的文件读取数据,而不是从键盘输入
重定向输出 1> 将输出结果保存到指定的文件(覆盖原有内容)
>> 将输出结果追加到指定的文件尾部
标准错误输出 2> 将错误信息保存到指定的文件(覆盖原有内容)
2>> 标准错误输出结果追加到指定的文件尾部
混合输出 &>无论对错都可以重定向 将标准输出、标准错误的内容保存到同一个文件中
  • &表示混合,&>和>&都表示将标准输出和错误输出重定向到同一个文件。
  • 命令>文件2>&1,表示把错误输出2重定向给前面的标准输出1(前面的1被省略了),即将错误输出和标准输出保存到同一个文件中。

管道符

管道符的作用是连接两个命令,将第一个命令的标准输出作为第二个命令的标准输入。同一行命令中可以使用多个管道符。

格式:cmd1|cmd2

变量

1.变量基础

常见shell变量的类型

  • 自定义变量:由用户自己定义,修改和使用
  • 预定义变量:Bash中内置的一类变量,系统预先设置好的,一般不可以修改
  • 环境变量:和系统环境有关的变量,由系统维护,用于设置工作环境($PATH)
  • 只读变量:只可以读取不可以更改(常量)
  • 位置变量:通过命令行给脚本传递参数

系统内置变量:PATH,UID,HOSTNAME,USER

变量的命令要求

  • 区分大小写
  • 不能使程序中的保留字和内置变量:如:if, for,hostname 。
  • 只能使用数字、字母及下划线,且不能以数字开头,注意:不支持短横线 “ - ”,和主机名相反。
  • 不要使用内置的变量,使用英文尽量使用词义通俗易懂,如 PATH 。
  • 大驼峰 StudentFirstName
  • 小驼峰 studentFirstName
  • 下划线 student_name
点击查看代码
name='value' 
变量名=变量值
直接字串:name='root'
变量引用:name="$USER"
命令引用:name=`COMMAND` 或者 name=$(COMMAND)
注意:变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存,脚本中的变量会随着脚本结束,也会自动删除

四大符号

点击查看代码
 { }    花括号 :确定变量其实起始结束的范围,只要有变量就加!
“  ”    双引号 :弱引用 smart,可以识别变量  
‘   ’   单引号 :强引用 stupid,不识别变量 (里面什么内容就输出什么内容)
`   `   反撇 :调用命令执行结果  ,效果与 $( ) 相同

2.自定义变量

取消变量:unset 变量名

追加变量的值:1变量名+=追加值 2重新定义

read -p

自定义变量:read [-p "提示信息"] 变量名

点击查看代码
[root@node1 ~]#  vim test2.sh    //编写脚本
  #!/bin/bash
  read -p "请输入一个正整数" a    //自定义变量
  read -p "请输入第二个正整数" b

  expr $a + $b  //expr只支持正整数
[root@node1 ~]#  bash test2.sh   //执行脚本
请输入一个正整数22
请输入第二个正整数33
55

设置变量的作用范围

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

可以通过内部命令export将指定的变量为全局变量,使用户定义的变量在所子shell环境中可以继续使用。

方法:

  • 格式1:export 变量名
  • 格式2:export 变量名=变量值
点击查看代码
`export作用:让子shell识别变量`

[root@node1 ~]#  abc=123           //设置局部变量abc
[root@node1 ~]#  echo $abc         //查看变量
123
[root@node1 ~]#  bash              //进入子shell
[root@node1 ~]#  echo $abc         //查看变量
                                   //为空,无效
[root@node1 ~]#  exit              //ctrl+D 退出子shell
[root@node1 ~]#  echo $abc
123
[root@node1 ~]#  export abc        //export  变量名 :定义全局变量
[root@node1 ~]#  bash              //进入子shell
[root@node1 ~]#  echo $abc         //查看变量
123                                //全局变量生效



输入bash进入子shell

ctrl+D组合exit 退出子shell

可以使用pstree 查看shell的环境

shell中的运算

  • 运算内容:1加+2减-3乘*4除/5取余(取模)%
  • 运算符号:$[]和$(())
  • 运算命令:expr和let
  • 运算工具:bc(系统自带)

注意:默认情况下bash只支持整数运算,只有bc能算小数

点击查看代码
`$[算术表达式]`
echo  $[算术表达式]  //调用

随机数生成器变量$RANDOM   (取值范围:0-32767)
[root@node1 ~]#  echo $[RANDOM%28]       //随机取0~27
13
[root@node1 ~]#  echo $[RANDOM%28+1]     //随机取1~28
22


`expr`
[root@node1 ~]#  expr 1+2
1+2
[root@node1 ~]#  expr 1 + 2  //注意空格!加减乘除前后要有空格
3


`let`
`特殊符号运算:`
[root@node1 ~]#  i=1
[root@node1 ~]#  let i++     //i++  自加1
[root@node1 ~]#  echo $i
2
[root@node1 ~]#  let i--     //i--  自减1
[root@node1 ~]#  echo $i
1
[root@node1 ~]#  let i+=3    //i+-3 自加3
[root@node1 ~]#  echo $i
4

求1~100的偶数和:
[root@node1 ~]#  seq -s + 0 2 100|bc   //从0开始,步长为2,取到100,求和
2550
求1~100的奇数和:
[root@node1 ~]#  seq -s + 1 2 100|bc   //从1开始,步长为2,取到100,求和
2500

`bash只能执行1次,使用eval命令可以执行2次`
[root@node1 ~]#  n=10
[root@node1 ~]#  echo {1..$n}      
{1..10}     //bash执行1次效果                      
[root@node1 ~]#  echo {1..10}
1 2 3 4 5 6 7 8 9 10    //bash执行2次效果
[root@node1 ~]#  eval echo {1..$n}   //使用eval命令可以让bash执行2次
1 2 3 4 5 6 7 8 9 10
eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。
该命令适用于那些一次扫描无法实现其功能的变量,该命令对变量进行两次扫描。

实验:system_info脚本

点击查看代码
[root@node1 ~]#  vim system_info.sh    //编写脚本
 
#!/bin/bash
PURPLE="\E[1;35m"
YELLOW="\E[1;33m"
END="\E[0m"

echo -e  "$YELLOW----------------------Host systeminfo--------------------$END"
echo -e  "HOSTNAME:     $PURPLE`hostname`$END"
echo -e  "IPADDR:       $PURPLE` ifconfig ens33|grep netmask| tr -s " " |cut -d " " -f3 `$END"
echo -e  "OSVERSION:    $PURPLE`cat /etc/redhat-release`$END"
echo -e  "KERNEL:       $PURPLE`uname -r`$END"
echo -e  "CPU:          $PURPLE`lscpu|grep '型号名称:'|tr -s ' '|cut -d : -f2`$END"
echo -e  "MEMORY:       $PURPLE`free -h |grep Mem |tr -s " " |cut -d " " -f2`$END"
echo -e  "DISK:         $PURPLE`lsblk |grep disk |tr -s " " |cut -d " " -f4`$END"
echo -e  "$YELLOW---------------------------------------------------------$END"

环境变量

1.由系统提前创建,用来设置用户的工作环境
2.可以使用env命令查看所有环境变量
3.需要记住的常用环境变量:

  • $USER 表示用户名称
  • $HOME 表示用户的宿主目录
  • $LANG 表示语言和字符集
  • $PWD 表示当前所在工作目录
  • $PATH 表示可执行用户程序的默认路径

环境变量的特性:

  • 可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量。
  • 一旦子进程修改从父进程继承的变量,将会新的值传递给孙子进程。
  • 一般只在系统配置文件中使用,在脚本中较少使用。

环境变量的配重文件

自定义的环境变量只是临时生效,退出系统后就会失效。需要将自定义的环境变量放入配置文件中,才会永久生效。配置文件可以用来长期变更或设置环境变量。

  • 全局配置文件: /etc/profile (修改此文件会作用于所有用户)
  • 用户独立的配置文件: ~/.bash_profile (修改这个文件只作用于当前用户)

只读变量
我们在定义shell变量时,默认定义的变量是可以被修改的,但有一种变量是不能修改的,就是只读变量。

只读变量只能被赋值一次。只读变量在取得初始值之后,只能进行读取操作,不能重新赋值或删除。

点击查看代码
[root@node1 ~]#  name=lisi        //定义一个变量name
[root@node1 ~]#  readonly name    //使用 readonly 修饰该变量 ,表明只读
[root@node1 ~]#  echo $name
lisi
[root@node1 ~]#  name=zhangsan    //无法重新赋值
-bash: name: 只读变量
[root@node1 ~]#  unset name       //无法使用unset删除
-bash: unset: name: 无法反设定: 只读 variable

位置变量
位置变量也称为位置参数。使用$n表示,n为数字序列号,且必须为整数。

如:$1、$2、…、$9 、${10}、${11}。

两位数需要加花括号 {},不然$10会被识别为:$1和0 。

点击查看代码
[root@node1 ~]#  vim weizhi.sh
  #!/bin/bash
  echo "$1"     //显示位置1的参数
  echo "$2"     //显示位置2的参数     
  echo "${10}"  //显示位置10的参数
  echo "$10"    

[root@node1 ~]#  bash weizhi.sh {a..z}
a   //对应$1
b   //对应$2
j   //对应$10
a0  //$10被识别为$1和0

预定义变量

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

预定义变量 含义
$? 上次执行命令的结果是否正确,0是正确,非0不正确
$0 当前脚本的名称
$$ 当前shell进程的pid号
$# 表示命令行中位置参数的总个数
$@ 把所有位置参数当作个体返回
$* 表示所有位置参数的内容看成一个整体返回
点击查看代码
[root@node1 ~]#  cat yudingyi.sh 
 #!/bin/bash

echo "当前脚本名称:$0"
echo "当前程序的PID:$$"
echo "位置参数的个数为:$#"
echo "显示所有的位置参数(个体):$@"
echo "显示所有的位置参数(整体):$*"

[root@node1 ~]#  bash yudingyi.sh  {0..10}
当前脚本名称:yudingyi.sh
当前程序的PID:14772
位置参数的个数为:11    //0~10的个数
显示所有的位置参数(个体):0 1 2 3 4 5 6 7 8 9 10
显示所有的位置参数(整体):0 1 2 3 4 5 6 7 8 9 10

posted @ 2024-05-14 17:08  leikj  阅读(9)  评论(0编辑  收藏  举报