shell脚本的判断式

news2024/11/25 20:38:35

文章目录

  • shell脚本的判断式
    • 利用test命令的测试功能
      • 关于某个文件名的【文件类型】判断
      • 关于文件的权限检测
      • 两个文件之间的比较
      • 关于两个整数之间的比较
      • 判定字符串的数据
      • 多重条件判定
      • 例题
    • 利用判断符号[ ]
      • 例题
    • shell脚本的默认变量($0、$1...)
      • 例题
      • shift:造成参数变量号码偏移

shell脚本的判断式

在之前的博客写过$?所代表的意义。此外,也通过&&及||来作为前一个命令执行返回值对于后一个命令是否要进行的根据。如果想要判断一个目录是否存在,当时我们使用的是ls这个命令搭配数据流重定向,最后配合%?来决定后续的命令进行与否,如下图。

image-20230425165939877

但是我们有更简单的方法来进行【条件判断】吗?利用【test】这个命令

利用test命令的测试功能

当我们要检测上面某些文件或是相关的属性时,利用test这个命令来进行检测

例如我要检查/csq 是否存在时

[root@localhost ~]# test -e /csq
[root@localhost ~]# echo $?
1

【test -e /csq】并没有显示任何信息,当我们输入了 echo $? 返回值不是0 代表是错误信息,我们也可以利用 &&及||来展销整个结果

例如我换一种方法检测一下/csq是否存在

[root@localhost ~]# test -e /csq && echo "this is exist" || echo "this is no exist"
this is no exist

最终结果告诉我们是【exist】还是【no exist】,那我们知道 -e 是测试一个【东西】存在不存在,如果我还想测试目录下的文件是否存在时,该用哪些参数呢?

关于某个文件名的【文件类型】判断

例如:test -e filename 表示存在否

测试的参数代表的意义
-e该【文件名】是否存在
-f该【文件名】是否存在且位文件(file)
-d该【文件名】是否存在且位目录
-b该【文件名】是否存在且为一个block device 设备
-c该【文件名】是否存在且为一个 character device
-S该【文件名】是否存在且为一个socket文件
-p该【文件名】是否存在且为一个FIFO文件
-L该【文件名】是否存在且为一个链接文件

关于文件的权限检测

例如:test -r filename 表示可读否

测试的参数代表的意义
-r检测该文件名是否存在且具有【可读】的权限
-w检测该文件名是否存在且具有【可写】的权限
-x检测该文件名是否存在且具有【可执行】的权限
-u检测该文件名是否存在且具有【SUID】的属性
-g检测该文件名是否存在且具有【SGID】的属性
-k检测该文件名是否存在且具有【SBIT】的属性
-s检测该文件名是否存在且为【非空文件】

两个文件之间的比较

例如:test file1 -nt file2

测试的参数代表的意义
-nt判断【file1】是否比【file2】新
-ot判断【file1】是否比【file2】旧
-ef判断【file1】与【file2】是否为同一个文件,可用在判断硬链接上面。
主要意义在于判定,两个文件是否均指向同一个inode

关于两个整数之间的比较

例如:test n1 -eq n2

测试的参数代表的意义
-eq两数值相等
-ne两数值不相等
-gtn1 大于 n2
-ltn1 小于 n2
-gen1 大于等于 n2
-len1 小于等于 n2

判定字符串的数据

测试的参数代表的意义
test -z string判定字符串是否为0?若string为空字符串,则为true
test string判断字符串是否非为0?若string为空字符串,则为false
test str1 == str2判定str1是否等于str2,若相等,则返回true
test str1 != str2判定str1是否等于str2,若相等,则返回true

多重条件判定

例如:test -r filename -a -x filename

测试的参数代表的意义
-a两条件同时成立。
例如:test -r file -a -x ,则file同时具有r与x权限时,才返回true
-o两条件任何一个成立
例如:test -r file -o -x ,则file具有r或x权限时,旧可返回true
!反相状态
例如:test ! -x file ,当file不具有x时,返回true

例题

首先我让用户输入一个文件名,我们判断:

  1. 整个文件是否存在,若不存在则给予一个【文件不存在】的信息,并中断程序
  2. 若这个文件存在,则判断它是个文件或目录,结果输出【这个文件是普通文件】或【这个文件是目录文件】
  3. 判断一下,执行者的身份对这个文件或目录所拥有者的权限,并输出权限输出
[root@localhost shelldir]# vim panduanfile.sh
#!/bin/bash
# 程序说明:
#      用户输入一个文件,程序进行了以下操作
#       1.输入的文件是否存在 2.是文件还是目录 3.文件的权限是什么?
# History
# 2023/04/28  csq
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:~/shelldir
export PATH
read -p "请用户输入一个文件:" filename
test -z ${filename} && echo "你必须输入一个文件!" && exit 0
test ! -e ${filename} && echo "文件${filename}不存在" && exit 0
test -f ${filename} && filetype="普通文件"
test -d ${filename} && filedir="目录文件"
test -r ${filename} && readfile="可读"
test -w ${filename} && writefile="可写"
test -x ${filename} && executefile="可执行"
echo -e "这个文件是:${filetype}${filedir}"
echo "$LOGNAME用户对这个${filetype}${filedir}拥有的权限有:${readfile}${writefile}${executefile}"

执行结果(如果文件存在)

[root@localhost shelldir]# vim panduanfile.sh
请用户输入一个文件:csq
这个文件是:目录文件
root用户对这个目录文件拥有的权限有:可读可写可执行

执行结果(如果文件不存在)

[root@localhost shelldir]# vim panduanfile.sh
请用户输入一个文件:ooo
文件ooo不存在

执行结果(在其他用户上面执行)

[csq@localhost /]$ sh panduanfile.sh 
请用户输入一个文件:aaa
这个文件是:普通文件
csq用户对这个普通文件拥有的权限有:可读

利用判断符号[ ]

其实除了test之外,我们还可以利用【[ ]】判断符号来进行数据判断。举例来说,如果我想知道${HOME}这个变量是否为空,可以这样做:

[root@localhost ~]# [ -z "$HOME" ] ; echo $?
1

使用中括号必须要特别注意,因为中括号用在很多地方,包括通配符和正则表达式等。所以说如果要在bash的语法当中使用中括号作为shell的判断式时,必须要注意中括号的两端需要有空格符来分隔。假设空格键使用【□】符号来表示,那你这些地方都需要有空格

[root@localhost ~]# [□"HOME"□==□"$MAIL"□]

你会发现上面的判断式中使用了两个等号【==】,其实在bash当中使用一个等号和两个等号的结果是一样3的。不过在一般常用程序的写法中,一个等号代表【变量的设置】两个等号则代表【逻辑判断(是与否之意)】由于问在中括号内重点在于【判断】而非【设置变量】,因此建议你使用两个等号

上面的例子在说明,两个字符串【$HOME】与【$MAIL】是否相同,相当于【 test ${HOME} == ${MAIL}】。而如果没有空白分隔例如:[${HOME}==${MAIL}],我们的bash就会显示错误信息。

  • 中括号[]内的每个组件都需要有空格来分隔
  • 在括号内的变量,最好都以双引号括起来
  • 在中括号内的常数,最好都以单或双引号括起来

例题

  1. 当执行一个程序的时候,这个程序会让用户选择Y或N
  2. 如果用户输入Y或y时,就显示【OK,继续】
  3. 如果用户输入N或n时,就显示【NO!,不继续】
  4. 如果不是Y/yN/n之内的字符,就显示【我不知道你输入的是什么】
[root@localhost shelldir]# vim continue.sh
#!/bin/bash
# 程序说明:
#  这个程序就是让用户做选择
# 时间:
# 2023/04/29
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:~/shelldir
export PATH
read -p "请输入一个Y/y,N/n我们来进行下一步:" yn
[ "${yn}" == "Y" -o "${yn}" == "y" ] && echo "OK,继续" && exit 0
[ "${yn}" == "N" -o "${yn}" == "n" ] && echo "NO,不继续" && exit 0
echo -e "\n我不知道你输入的是什么\a"

由于输入正确(Yes)的方法有大小写之分,不论输入大写或小写y都是可以的,此时判断式内就得要两个判断才行,由于是任何一个成立即可(大写或小写的y),所以这里使用-o连接两个判断。

执行结果如下(输入Y)

[root@localhost shelldir]# sh continue.sh 
请输入一个Y/y,N/n我们来进行下一步:Y
OK,继续

执行结果如下(没输入)

[root@localhost shelldir]# sh continue.sh 
请输入一个Y/y,N/n我们来进行下一步:

我不知道你输入的是什么

shell脚本的默认变量($0、$1…)

我们知道命令可以带有选项参数,例如 【ls -al】可以查看包含隐藏文件的所有的属性与权限。那么shell脚本能不能再脚本文件名后面带有参数呢?

例如:如果你想要重新启动系统网络,可以这样做

[root@localhost ~]# file /etc/init.d/network 
/etc/init.d/network: Bourne-Again shell script, ASCII text executabl
# 使用file来查询后,系统告知这个文件是个bash可执行的文件
[root@localhost ~]# /etc/init.d/network restart

restart是重启的意思,上面的命令可以【重新启动 /etc/init.d/network 这个程序】。那么如果你再 【/etc/init.d/network 】加个个stop ,就直接关闭服务了。

那么脚本怎么完成这个功能呢?其实脚本针对参数已经设置好了一些变量名称,对应如下

/path/to/scriptname    opt1  opt2  opt3  opt4
     $0                 $1    $2    $3    $4

执行的脚本文件名为 $0这个变量,第一个接的参数就是$1。所以只要我们在脚本里面善用$1的话,就可以很简单地立即执行某些命令功能了。除了这些变量之外,还有一些较为特殊的变量可以在脚本内使用来调用这些参数

  • $#:代表后接的参数【个数】,以上表为例这里显示为【4】
  • $@:代表【"$1" "$2" "$3" "$4"】之意,每个变量都是独立的(用双引号括起来)
  • $*:代表【“$1c$2c$3c$4c”】,其中c为分隔符,默认为空格,所以本例中代表【“$1 $2 $3 $4”】

$@和$*一般情况下可以直接记忆$@

例题

假设我要执行要个可以携带的参数脚本,执行该脚本后屏幕会显示如下数据:

  • 程序的文件名是什么?
  • 共有几个参数
  • 如果文件名后面没跟参数就提示他没跟参数
  • 若参数的个数小于2则告知用户参数数量太少
  • 全部的参数内容是什么
  • 第一个参数是什么
  • 第二个参数是什么
[root@localhost shelldir]# vim args_shibie.sh
#!/bin/bash
# 程序说明:
#    展示以下执行shell脚本的文件名,以及参数
# 时间:
# 2023/04/29
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
export PATH
echo "这个文件名是:${0}"
echo "共有$#个参数"
[ "$#" == "0" ] && echo "文件名后面没跟参数"  && exit 0
[ "$#" -lt 2 ]  && echo "参数太少"  && exit 0
echo "全部的参数内容是:$@"
echo "第一个参数是:$1"
echo "第二个参数是:$2"

执行结果(跟了参数)

[root@localhost shelldir]# sh args_shibie.sh csq zzg  zzc
这个文件名是:args_shibie.sh
共有3个参数
全部的参数内容是:csq zzg zzc
第一个参数是:csq
第二个参数是:zzg

执行结果(没跟参数)

[root@localhost shelldir]# sh args_shibie.sh 
这个文件名是:args_shibie.sh
共有0个参数
文件名后面没跟参数

shift:造成参数变量号码偏移

除此之外,脚本后面所接的变量是否能够进行偏移(shift)呢?什么是偏移?我们举例来说明,还是用上面的例题。

[root@localhost shelldir]# vim args_shibie.sh
#!/bin/bash
# 程序说明:
#    显示shift造成的参数变量号码偏移了多少
# 时间:
#  2023/04/29
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
export PATH
echo "共有$#个参数"
echo "全部的参数内容是:$@"
shift
echo "共有$#个参数"
echo "全部的参数内容是:$@"
shift 3
echo "共有$#个参数"
echo "全部的参数内容是:$@"

执行结果如下

[root@localhost shelldir]# sh args_shibie.sh aa bb cc dd ff gg hh
共有7个参数
全部的参数内容是:aa bb cc dd ff gg hh
共有6个参数
全部的参数内容是:bb cc dd ff gg hh
共有3个参数
全部的参数内容是:ff gg hh

看到上面的结果就可以知道,shift会移动变量,而且shift后面可以接数字,代表拿掉最前面的几个参数的意思。上面执行结果中,第一次进行shift后它的显示情况是【 aa bb cc dd ff gg hh 】所以只剩下6个参数,第二次直接拿掉三个,就变成【 aa bb cc dd ff gg hh 】。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/475916.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux安装Mysql操作步骤详解

目录 1. 检测当前系统中是否安装了MySql数据库 2. 使用FinalShell自带的上传工具将jdk的二进制发布包上传到Linux 3. 解压并解包到/usr/local/mysql(便于区分) 第一步:将包先移动到该目录下 第二步:解压解包 第三步&#xff1a…

LeetCode 105.106. 从前序|后序与中序遍历序列构造二叉树 | C++语言版

LeetCode 105. 从前序与中序遍历序列构造二叉树 | C语言版 LeetCode 105. 从前序与中序遍历序列构造二叉树题目描述解题思路思路一:使用递归代码实现运行结果参考文章: 思路二:减少遍历节点数代码实现运行结果参考文章: LeetCode …

C语言复习笔记1

1.不同数据类型所占字节数。 bit 01二进制的比特位 byte 字节 8 bit 比特 之后的单位都是以1024为倍数 #include<stdio.h> #include<unistd.h>int main() {printf("sizeof(char)%d\n",sizeof(char));printf("sizeof(short)%d\n",sizeof(sh…

JavaScript 笔记

1 简介 JavaScript 诞生于1995年&#xff0c;是由网景公司发明&#xff0c;起初命名为LiveScript&#xff0c;后来由于SUN公司的介入&#xff0c;更名为 JavaScript。1996年微软在其最新的IE3浏览器中引入了自己对JavaScript的实现JScript&#xff0c;于是市面上就存在两个版本…

Mybatis 框架 ( 三 ) Mybatis-Plus

4.Mybatis-plus 官网 : https://www.baomidou.com/ MyBatis-Plus 是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上封装了大量常规操作&#xff0c;减少了SQL的编写量。 4.1.Maven依赖 使用时通常通过Springboot框架整合使用 并且使用Lombok框架简化实体类 <…

软件测试——基础篇(软件测试的生命周期和BUG的概念)

目录 一、软件测试生命周期 1. 软件生命周期 2. 软件测试生命周期 二、BUG 1. 如何描述一个BUG 2. BUG的级别 3. BUG的生命周期 一、软件测试生命周期 1. 软件生命周期 软件生命周期&#xff1a;需求分析&#xff0c;计划&#xff0c;设计&#xff0c;编码&#xff0c;…

20 printf 的调试

前言 在最开始的 cmd 编程中, 我们会使用到的最常见的输出, 包括一些时候调试的时候 我们最常使用到的函数 那肯定是 printf 了 我们这里来调试一下 这个 printf 还有一个原因是 之前在调试 malloc 的时候, malloc 虚拟内存分配的调试(1) 可以发现, 不仅仅是在 malloc 的时…

Codeforces Round 865 (Div. 2)

6 problems. ABC过, DE没想出来, F没看. https://codeforces.com/contest/1816 A. Ian Visits Mary 分析 - AC 每次跳跃&#xff0c;横纵互质。 限于数据量&#xff0c;不能枚举。 1与任何数互质。考虑从(0,0)跳到(1,y)&#xff0c;这一步一定合法&#xff1b;再从(1,y)跳到…

Netty小白入门教程

一、概述 1.1 概念 Netty是一个异步的基于事件驱动(即多路复用技术)的网络应用框架&#xff0c;用于快速开发可维护、高性能的网络服务器和客户端。 1.2 地位 Netty在Java网络应用框架中的地位就好比&#xff0c;Spring框架在JavaEE开发中的地位。 以下的框架都使用了Nett…

C++017-C++文件读写应用

文章目录 C017-C文件读写应用C文件读写应用CSP-J目标1. 文件的基本概念、文本文件的基本操作关闭文件 文件操作-写入文本文件2.文件读写操作基本案例seekg() 和 tellg() 函数来读取文件中的数据 2. 文本文件类型与二进制文件类型3. 文件重定向、文件读写等操作 在练习&#xff…

56.网页设计规则#4_图标

使用好的图标 使用一个好的图标包&#xff0c;有大量的免费和付费图标包 图标工具推荐&#xff1a; ● Phosphor icons ● ionicons ● ICONS8 只使用一个图标包。不要混合不同图标包中的图标 使用SVG图标或图标字体。不要使用位图图像格式(.jpg and .png)! 调整网站个性!圆…

Android 中的跨进程数据块传递

Android 的 Binder 进程间通信机制主要用于实现远程过程调用 RPC&#xff0c;Android 系统中进程之间的大块数据传递&#xff0c;如音频数据&#xff0c;出于效率等原因&#xff0c;一般不直接用 Binder 机制。Binder 库提供了基于共享内存外加 Binder 机制的跨进程文件描述符传…

每月一书(202304)《RxJava2.x实战》

[TOC] 又到了每月一书的时间&#xff0c;本月阅读的是技术相关书籍《RxJava2.x实战》&#xff0c;下面分享一下我阅读完后的体会。 主要内容 本书主要介绍了RxJava这个框架&#xff0c;框架版本是2.x。主要内容包含三大部分&#xff1a; 框架的原理和使用方法框架中各类操…

git alias

git alias 其实之前就用过一些 alias&#xff0c;比如说 git reflog show 就是 git log -g --abbrev-commit --prettyoneline 的 alias&#xff0c;一般 alias 可以存储到 git 的 config 文件&#xff0c;repo 等级的在 .git 下&#xff0c;global 的一般在 ~/.gitconfig 或者…

【flask】三种路由和各自的比较配置文件所有的字母必须大写if __name__的作用核心对象循环引用的几种解决方式--难Flask的经典错误上下文管理器

三种路由 方法1&#xff1a;装饰器 python C#, java 都可以用这种方式 from flask import Flask app Flask(__name__)app.route(/hello) def hello():return Hello world!app.run(debugTrue)方法2: 注册路由 php python from flask import Flask app Flask(__name__)//app…

【前端面经】JS-事件循环

什么是事件循环(Event Loop)? 众所周知, Javascript是一门单线程的语言, 单线程即同一时间只能做一件事, 但这并不意味着JavaScript在执行代码的过程中就会一直阻塞,而解决单线程不阻塞的这个机制就叫做事件循环(Event Loop), 也就是同步和异步的概念. 任务执行流程 在JS中…

PS滤镜插件-Nik Collection介绍

PS滤镜插件-Nik Collection介绍 什么是Nik CollectionNik Collection都包含什么&#xff1f; 什么是Nik Collection Nik Collection是一款PS滤镜插件套装&#xff0c;其包含了八款PS插件&#xff0c;功能涵盖修图、调色、降噪、胶片滤镜等方面。Nik Collection 作为很多摄影师…

redhat 安装oracle 11g

这里写目录标题 1、数据库下载和安装文档1.2、安装文档1.3、license种类解释&#xff08; XE版 标准本 个人版 企业版&#xff09;1.4、在安装完oracle后再创建数据库1.5、DBA的文档1.6、Automatic Storage Management Administrators Guide1.7、数据库备份恢复手册1.8、Overvi…

系统集成项目管理工程师 笔记(第15章 信息(文档)和配置管理)

文章目录 软件文档的分类&#xff08;1&#xff09;开发文档&#xff1a;描述开发过程 本身&#xff08;2&#xff09;产品文档&#xff1a;描述开发过程的 产物&#xff08;3&#xff09;管理文档&#xff1a;记录项目管理的信息 文档的质量可以分为四级&#xff08;1&#xf…

03_Uboot网络命令与MMC和文件操作命令

目录 网络操作命令 ping命令 nfs 命令 tftp 命令 EMMC和SD卡操作命令 mmc info命令 mmc rescan命令 mmc list 命令 mmc dev 命令 mmc part命令 mmc read 命令 mmc write 命令 mmc erase 命令 FAT 格式文件系统操作命令 fatinfo 命令 fatls 命令 fstype 命令 …