Linuxshell脚本-格式-变量-条件测试

1、Linuxshell脚本格式

脚本文件名称格式:

         1、NAME.sh。脚本文件名称必须以 .sh 结尾

         脚本编辑第一行必须包括shell声明序列:#!

         添加注释,注释以#开头

            2、加3执行权限

         给予执行权限,在命令行上指定脚本的绝对或相对路径

            3、运行脚本

          直接运行解释器,将脚本作为解释器程序的参数运行

示例:

[17:48:44 root@centos8 /data/bashs]#cat hello.sh 
#!/bin/bash
#20220413
#practice
echo "hello world"

 1.1shell脚本调试

  只能检测脚本中的语法错误,但无法检查处命令错误,但不真正执行脚本

调试检查语法

bash -n /path/to/some_script

调试并执行

bash -x /path/to/some_script

   总结:脚本错误常见的三种

语法错误,会导致后续的命令不继续执行,可以用bash -n 检查错误,提示的出错行不一定是准确的

 

命令错误,默认后续的命令还会继续执行,用bash -n 无法检查出来,可以使用bash -x 进行观察

 

逻辑错误,只能使用bash -x 进行观察

2.变量

  变量类型

  • 内置变量,如:PS1, PATH, UID, HOSTNAME等
  • 用户自定义变量

 不同的变量存放的数据不同,决定了以下

  • 数据存储方式
  • 参与的运算
  • 表示的数据范围

 变量数据类型:

  • 字符
  • 数值:整形,浮点型,bash不支持浮点型

2.1.shell变量命名法则

  命名要求

  • 区分大小写
  • 不能使用程序中的保留字和内置变量;如:if,for
  • 只能使用数字,字母下划线,且不能以数字开头,注意:不支持短横线“ - ”,和主机名相反

  命名习惯

  • 见名知义,用英文单词命名,并体现出实际作用,不要简写。
  • 变量名大写
  • 局部变量小写
  • 函数名小写
  • 大驼峰StudentNmae
  • 小驼峰studentName
  • 下划线student_name

2.2变量定义和引用 

  变量的生效范围等标准划分变量类型
  • 普通变量:生效范围为当前shell进程;对当前shell之外的其他shell进程,包括当前shell的子shell进程均无效
  • 环境变量:生效范围为当前shell进程及其子进程
  • 本地变量:生效范围为当前shell进程中某代码片断,通常指函数
变量赋值
    name='value'
           value
              (1) 可以是直接字串;name="username"
              (2) 变量引用:name="$username"
              (3) 命令引用:name=`COMMAND`, name=$(COMMAND)   

注意:变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存,脚本中的变量会随着脚本结束,也会自动删除
  

变量引用

    $name
    ${name}

" "弱引用,其中的变量引用会替换为变量值;
' '强引用,其中的变量引用不会被替换为变量值,而保持原字符串

显示以定义的所有变量
set
删除变量
unset name

2.3环境变量

  环境变量:

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

  变量声明和赋值

声明并赋值

export  name=VALUE
declare -x name=VALUE


或者分两步实现
name= VALUE
export name

  变量引用:

$name
${name}

  显示所有环境变量

env
printenv
export
declare -x

查看指定进程的环境变量
cat /proc/$PID/environ  (查看PID  pstree -p)

删除变量
unset name

bash的内建的环境变量
    PATH,SHELL,USER,UID,HOME,PWD等

 2.4只读变量

  只读变量:只能声明定义,但后续不饿能修改和删除,即常量

  声明只读变量:

  

readonly name
decalare -r name

  查看只读变量

readonly  [-p]
declare  -r

2.5位置变量

  位置变量:在bash shell 中内置的变量,在脚本你代码中调用通过命令行传递给脚本的参数

$1,$2, . . . 对应第1个、第2个等参数,sheft [n]换位置
$0    命令本身,包括路径
$*    传递给脚本的所有参数,全部参数合为一个字符串
$@   传递给脚本的所有参数,每个参数为独立字符串
$#    传递给脚本的参数个数


注意:$@ $* 只在被双引号包起来的时候才会有差异


清空所有位置变量

set --

 2.6推出状态码变量

  进程执行后,将变量$?保存状态码的相关数字,不同的值反应成功或失败,$?取值范例0-255

$?的值为0                #代表成功
$?的值是1到255          #代表失败

用户可以在脚本中使用以下命令自行定义推出状态码

exit [n]

  注意:

  • 脚本中一旦遇到exit命令,脚本会立即终止;终止推出状态取决于exit命令后面的数字
  • 如果exit后面无数子,终止退出状态取决于exit命令前面命令执行结果
  • 如果没有exit命令,即未给脚本指定推出状态码,整个脚本的推出状态码取决于脚本中执行的最后一条命令的状态码

3.1条件测试命令

  条件测试:判断某需求是否满足,需要由测试机制来实现,专用的测试表示式需要测试命令辅助完成测试过程,实现评估布尔声明,以便使用在条件性环境下进行执行

  若真,则状态码变量$?返回0

  若假,则状态码变量$?返回1

  条件测试命令

  • test EXPRESSION
  • [ EXPRESSION ]  #和test等价,建议使用[  ]
  • [[ EXPRESSION ]] 相当于增强版的[  ],支持[  ]的用法,且支持扩展正则表达式和通配符

  注意: 

    EXPRESSION前后必须由空白字符

3.1.1 数值测试

-eq   是否等于
-ne   是否不等于
-gt   是否大于
-ge   是否大于等于
-lt   是否小于
-le   是否小于等于

3.1.2 文件测试

  存在性测试

-a FILE:同 -e
-e FILE: 文件存在性测试,存在为真,否则为假
-b FILE:是否存在且为块设备文件
-c FILE:是否存在且为字符设备文件
-d FILE:是否存在且为目录文件
-f FILE:是否存在且为普通文件
-h FILE 或 -L FILE:存在且为符号链接文件
-p FILE:是否存在且为命名管道文件
-S FILE:是否存在且为套接字文件

  文件权限测试:

-r FILE:是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行
-u FILE:是否存在且拥有suid权限
-g FILE:是否存在且拥有sgid权限
-k FILE:是否存在且拥有sticky权限

注意:最终结果由用户对文件的实际权限决定,而非文件属性决定

 

  文件属性测试

-s FILE         #是否存在且非空
-t fd          #fd 文件描述符是否在某终端已经打开
-N FILE        #文件自从上一次被读取之后是否被修改过
-O FILE        #当前有效用户是否为文件属主
-G FILE        #当前有效用户是否为文件属组
FILE1 -ef FILE2    #FILE1是否是FILE2的硬链接
FILE1 -nt FILE2   #FILE1是否新于FILE2(mtime)
FILE1 -ot FILE2   #FILE1是否旧于FILE2

3.2 关于()和 {}

  (CMD1;CMD2;...)和 { CMD1;CMD2;...; } 都可以将多个命令组合在一起,批量执行

( list ) 会开启子shell,并且list中变量赋值及内部命令执行后,将不再影响后续的环境
帮助参看:man bash 搜索(list)
{ list; } 不会启子shell, 在当前shell中运行,会影响当前shell环境
帮助参看:man bash 搜索{ list; }

  示例:()和{}

[12:56:47 root@centos8 ~]#name=li;( echo $name;name=yan;echo $name ); echo $name
li
yan
li
[12:57:35 root@centos8 ~]#name=li;{ echo $name;name=yan;echo $name; }; echo $name
li
yan
yan
[12:57:53 root@centos8 ~]#
[13:00:08 root@centos8 ~]#( cd /data;ls )
bashs  f1.txt  fstab  lianx  passwd  seq.log  system_info.sh  test
[13:00:15 root@centos8 ~]#pwd
/root
[13:00:20 root@centos8 ~]#{ cd /data;ls; }
bashs  f1.txt  fstab  lianx  passwd  seq.log  system_info.sh  test
[13:00:26 root@centos8 /data]#pwd
/data
[13:00:29 root@centos8 /data]#

3.3组合测试条件

3.3.1 第一种方式

[ EXPRESSION1 -a EXPRESSION2 ] 并且,EXPRESSION1和EXPRESSION2都是真,结果才为真
[ EXPRESSION1 -o EXPRESSION2 ] 或者,EXPRESSION1和EXPRESSION2只要有一个真,结果就为
真
[ ! EXPRESSION ] 取反

说明: -a 和 -o 需要使用测试命令进行,[[ ]] 不支持

3.3.2第二种方式

COMMAND1 && COMMAND2   #并且,短路与,代表条件性的AND THEN
如果COMMAND1 成功,将执行COMMAND2,否则,将不执行COMMAND2
COMMAND1
|| COMMAND2   #或者,短路或,代表条件性的OR ELSE
如果COMMAND1 成功,将不执行COMMAND2,否则,将执行COMMAND2
! COMMAND #非,取反

 4、使用read命令来接受输入

  使用read来把输入值分配给一个或多个shell变量,read从标准输入中读取值,给每个单词分配一个变 量,所有剩余单词都被分配给最后一个变量,如果变量名没有指定,默认标准输入的值赋值给系统内置 变量REPLY

  格式

read [options] [name ...]


常见选项:

-p       指定要显示的提示
-s       静默输入,一般用于密码
-n N     指定输入的字符长度N
-d '字符'    输入结束符
-t N     TIMEOUT为N秒

 作业练习

9、编写脚本disk.sh,显示当前硬盘分区中空间利用率最大的值

[10:19:53 root@centos8 /data/bashs]#cat disk.sh 
#!/bin/bash
#
#Maximum disk space
#USAGE 使用率 
#DISKINFO=`df -h | grep "$USAGE"`
USAGE=`df -h |grep -v "Filesystem" |tr -s ' ' |cut -d' ' -f5 |sort -nr|head -1`
DISK=`df -h | grep "$USAGE" | tr -s ' ' | cut -d' ' -f1`
SIZE=`df -h | grep "$USAGE" | tr -s ' ' | cut -d' ' -f2`
USED=`df -h | grep "$USAGE" | tr -s ' ' | cut -d' ' -f3`
AVAIL=`df -h | grep "$USAGE" | tr -s ' ' | cut -d' ' -f4`
FDISK=`df -h | grep "$USAGE" | tr -s ' ' | cut -d' ' -f6`
echo "diskinfo:"

#echo "$DISKINFO"

echo "$DISK"
echo
echo  -e "size:$SIZE; userd:\E[1;31m$USED\E[0m; avail:\E[1;32m$AVAIL\e[0m; use%:\E[1;35m$USAGE\e[0m "
echo
echo -e  "\e[1;36mdisk-partition: $DISK\e[0m"
echo "File-directory: $FDISK"

10、编写脚本 systeminfo.sh,显示当前主机系统信息,包括:主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小

 

 

[17:08:55 root@centos8 /data/bashs]#cat  systeminfo.sh 
#!/bin/bash
#systeminfo
#20220415
#


echo
echo "**************************HOST systeminfo*****************************"
echo "HOSTNAME:               `hostname`"
echo "IPADDR:             `ifconfig |head -2|tail -1|grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}'|head -1`"
echo "OSVERSION:    `cat /etc/redhat-release`"
echo "KERNEL:            `uname -r`"
echo "CPU:    `lscpu | grep "Model name"|tr -s ' '|cut -d":" -f2|head -1`"
echo "MEMORY:               `free -h | tr -s ' '|grep Mem|cut -d' ' -f2`"
echo "DISK               `lsblk | grep "^sda"|tr -s ' ' | cut -d" " -f4`"
echo "***********************************************************************"

 

 

posted @ 2022-04-15 17:40  goodbay说拜拜  阅读(333)  评论(0编辑  收藏  举报