首页 > 系统相关 >Linux学习记录13——shell脚本

Linux学习记录13——shell脚本

时间:2024-03-24 19:32:28浏览次数:24  
标签:脚本 13 shell 是否 运算符 命令 Shell 测试 Linux

一.学习的内容

        shell终端解释器提供了诸如循环、分支等高级编程语言才有的控制结构。shell脚本命令的工作方式有下面两种:

        交互式:用户每输入一条命令就立即执行

        批处理(Batch):由用户事先编写好一个完整的Shell脚本,Shell会一次性执行脚本中诸多的命令。

        在Shell脚本中不仅会用到前面学习过的很多Linux命令以及正则表达式、管道符、数据流重定向等语法规则,还需要把内部功能模块化后通过逻辑语句进行处理,最终形成日常所见的Shell脚本。

1、编写简单的脚本

        其实使用Vim编辑器把Linux命令按照顺序依次写入到一个文件中,就是一个简单的脚本了。

        例如,如果想查看当前所在工作路径并列出当前目录下所有的文件及属性信息,实现这个功能的脚本应该类似于下面这样:

图1  编写脚本

        Shell脚本文件的名称可以任意,但为了避免被误以为是普通文件,建议将.sh后缀加上,以表示是一个脚本文件。

        在上面的这个example.sh脚本中实际上出现了3种不同的元素:第一行的脚本声明(#!)用来告诉系统使用哪种Shell解释器来执行该脚本;第二行的注释信息(#)是对脚本功能和某些命令的介绍信息,使得自己或他人在日后看到这个脚本内容时,可以快速知道该脚本的作用或一些警告信息;第三、四行的可执行语句也就是我们平时执行的Linux命令了。那我们来执行一下看看结果:

图2  bash命令运行

        除了上面用Bash解释器命令直接运行Shell脚本文件外,第二种运行脚本程序的方法是通过输入完整路径的方式来执行。但默认会因为权限不足而提示报错信息,此时只需要为脚本文件增加执行权限即可(详见第5章)。 

2、接受用户参数

        为了让Shell脚本程序更好地满足用户的一些实时需求,以便灵活完成工作,必须要让脚本程序能够像之前执行命令时那样,接收用户输入的参数。

        其实,Linux系统中的Shell脚本语言早就考虑到了这些,已经内设了用于接收参数的变量,变量之间使用空格间隔。例如,$0对应的是当前Shell脚本程序的名称$#对应的是总共有几个参数$*对应的是所有位置的参数值$?对应的是显示上一次命令的执行返回值,而$1、$2、$3……则分别对应着N个位置的参数值。

        实例如下图所示:

图3   接收参数

         运行刚才编写的shell脚本:

图4  运行并输入参数

3、判断用户的参数 

         在前面讲到,系统在执行mkdir命令时会判断用户输入的信息,即判断用户指定的文件夹名称是否已经存在,如果存在则提示报错;反之则自动创建。Shell脚本中的条件测试语法可以判断表达式是否成立,若条件成立则返回数字0否则便返回非零值。条件测试语法的执行格式如图5所示。切记,条件表达式两边均应有一个空格。  

图5   格式

按照测试对象来划分,条件测试语句可以分为4种: 

        文件测试语句;

        逻辑测试语句;

        整数值比较语句;

        字符串比较语句。

        文件测试即使用指定条件来判断文件是否存在或权限是否满足等情况的运算符,具体的参数如下表所示。

表1 文件测试所用参数
操作符作用
-d测试文件是否为目录类型
-e测试文件是否存在
-f判断是否为一般文件
-r测试当前用户是否有权限读取
-w测试当前用户是否有权限写入
-x测试当前用户是否有权限执行

        下面使用文件测试语句来判断 /etc/fstab 是否为一个目录类型的文件,然后通过Shell解释器的内设 $? 变量显示上一条命令执行后的返回值。如果返回值为0,则目录存在;如果返回值为非零的值,则意味着它不是目录,或这个目录不存在: 

图6    -d 参数判断是否为目录文件

         再使用文件测试语句来判断 /etc/fstab 是否为一般文件,如果返回值为0,则代表文件存在,且为一般文件:

图7   -f 参数判断是否为一般文件

        由上述两个命令可知,/etc/fstab 是一般文件。

        逻辑语句用于对测试结果进行逻辑分析,根据测试结果可实现不同的效果。例如在Shell终端中逻辑“与”的运算符号是&&,它表示当前面的命令执行成功后才会执行它后面的命令,因此可以用来判断 /dev/fstab 文件是否存在,若存在则输出Exist字样。

图8   &&

        除了逻辑“与”外,还有逻辑“或”,它在Linux系统中的运算符号为 || ,表示当前面的命令执行失败后才会执行它后面的命令。 由于 /etc/fstab 不是一个目录,所以它会执行后面的echo 命令。

图9  ||

        第三种逻辑语句是“非”,在Linux系统中的运算符号是一个叹号(!),它表示把条件测试中的判断结果取相反值。也就是说,如果原本测试的结果是正确的,则将其变成错误的;原本测试错误的结果,则将其变成正确的。

        /etc 是一个目录文件,故 -d /etc 返回值应该是0,但是前面又加了  !  ,故变成1,所以会执行 后面的echo 命令。

图10  非!

        当前我们正在登录的即为管理员用户—root。下面这个示例的执行顺序是,先判断当前登录用户的USER变量名称是否等于root,然后用逻辑“非”运算符进行取反操作,效果就变成了判断当前登录的用户是否为非管理员用户。最后若条件成立,则会根据逻辑“与”运算符输出user字样;若条件不满足,则会通过逻辑“或”运算符输出root字样。

图11  组合逻辑

         整数比较运算符仅是对数字的操作,不能将数字与字符串、文件等内容一起操作,而且不能想当然地使用日常生活中的等号、大于号、小于号等来判断。因为等号与赋值命令符冲突,大于号和小于号分别与输出重定向命令符和输入重定向命令符冲突。因此一定要使用规范的整数比较运算符来进行操作。可用的整数比较运算符如表2所示。

表 2 可用的整数比较运算符
操作符作用
-eq是否等于
-ne是否不等于
-gt是否大于
-lt是否小于
-le是否等于或小于
-ge是否大于或等于

         先测试一下10是否大于10以及10是否大于等于10(通过输出的返回值内容来判断):

图12   -ge参数

        返回结果为0 ,说明10 大于等于 10 成立。

        曾经讲过free命令,它能够用来获取当前系统正在使用及可用的内存量信息。接下来先使用free -m  命令查看内存使用量情况(单位为MB),然后通过 “grep Mem:” 命令过滤出剩余内存量的行,再用    awk '{print $4}'   命令只保留第4列。

图13  剩余内存量

        如果想把这个命令写入到Shell脚本中,那么建议把输出结果赋值给一个变量,以方便其他命令进行调用:(注意使用了反引号,给变量赋值时等号两边不能有空格)

图14  给变量赋值

        我们使用整数运算符来判断内存可用量的值是否小于1024,若小于则会提示“Insufficient Memory”(内存不足)的字样:

图15  -lt 参数

         字符串比较语句用于判断测试字符串是否为空值,或两个字符串是否相同。它经常用来判断某个变量是否未被定义(即内容为空值),理解起来也比较简单。字符串比较中常见的运算符如表3所示。

表3 常见的字符串比较运算符
操作符作用
=比较字符串内容是否相同
!=比较字符串内容是否不同
-z判断字符串内容是否为空

        接下来通过判断String变量是否为空值,进而判断是否定义了这个变量: 

图16   -z参数判断变量是否被定义

        由上图可知,String变量内容为空值(未被定义),而FreeMem 被定义。

        再次尝试引入逻辑运算符来试一下。当前语系的环境变量值LANG不是英语(en.US)时,则会满足逻辑测试条件并输出“Not en.US”(非英语)的字样:

图17    加入逻辑运算符

         可以发现,在字符串比较时,等号两边要有空格,否则会被认为是连一块的字符;此外,加不加双引号都无所谓。        

二.本次学习遇到的问题

        1、使用Vim编辑器,编辑shell脚本时,前面的    #!/bin/bash  可以省略吗?(测试过省略之后,再用bash 命令执行也是可以的)

        2、怎么切换成中文

        3、&& 和 || 的关系,以及和在C语言中的不同点

        4、等号两边的空格问题,有的需要空(字符串的比较),而有的不需要(变量赋值)?

三、问题的答案及解决办法

1、

        在某些情况下,你可以省略这一行,但这取决于你的使用场景。如果你打算手动执行这个脚本,并且已经将Bash作为默认的解释器配置,那么省略这一行通常是可以的,系统会默认使用Bash来执行。但是,在编写可供他人使用的脚本时,建议保留这一行,以确保脚本可以在不同的系统上正确执行,即使默认解释器不同也不会出错。 

        

3、

相似之处:
        逻辑操作符: 在两种情况下,&& 和 || 都是逻辑操作符。
        短路求值: 在两种情况下,&& 和 || 都支持短路求值。这意味着如果在 && 中第一个条件为假,则不会执行第二个条件;而在 || 中,如果第一个条件为真,则不会执行第二个条件。

不同之处:
        语言环境: && 和 || 在Shell中是控制结构,用于在条件语句中执行命令,而在C语言中是逻辑运算符,用于组合逻辑表达式。

        返回值: 在Shell中,&& 和 || 返回的是最后一个执行的命令的返回值。在C语言中,&& 和 || 返回的是布尔值(1表示真,0表示假)。

        用途: 在Shell中,&& 通常用于在前一个命令成功后执行下一个命令,而 || 通常用于在前一个命令失败后执行下一个命令。在C语言中,&& 和 || 用于逻辑与和逻辑或运算。

4、

在RHEL 8中,[ 1=2 ] 和 [ 1 = 2 ] 是不同的。它们之间的差异在于空格的位置。

[ 1=2 ] 实际上是将字符串"1=2"传递给了 [ 命令,而不是比较1和2是否相等。因此,此条件将被视为字符串的非空条件,返回0(真)。

而 [ 1 = 2 ] 是正确的条件语法,它会比较1和2是否相等。因此,这个条件会返回1(假)。

在bash shell中,条件测试语句 [ ... ] 要求空格来分隔其中的组件,否则bash将把整个字符串视为单个参数传递给测试命令。

标签:脚本,13,shell,是否,运算符,命令,Shell,测试,Linux
From: https://blog.csdn.net/qq_53729037/article/details/136973183

相关文章

  • linux 下安装mysql redis
    查看是否安装mysql:rpm-qa|grepmysql获取mysql版本:wget-i-chttp://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm安装:rpm-ivhmysql-community-release-el7-5.noarch.rpmyuminstallmysql-community-serversystemctlstartmysqldsystemctlrest......
  • 【Linux应用开发】gcc编译过程
            gcc是一个c编译器,​可以将源代码转换为可执行程序。编译过程包括了预处理、编译、汇编和链接这四个阶段。预处理(Preprocessing):在预处理阶段,源代码会经过预处理器的处理,包括展开宏定义、包含头文件、条件编译等操作。预处理器会生成一个经过预处理的中间文件......
  • Linux收到一个网络包是怎么处理的?
    目录摘要​编辑1从网卡开始2硬中断,有点短2.1GameOver3接力——软中断3.1NET_RX_SOFTIRQ软中断的开始3.2数据包到了协议栈3.3网络层处理3.4传输层处理4应用层的处理5总结摘要    一个网络包的接收始于网卡,经层层协议栈的解析,终于应用层。......
  • Docker的Linux网络基础
    Docker技术依赖于近年来Linux内核虚拟化技术的发展,所以Docker对Linux内核有很强的依赖。本文将Docker使用到的与Linux网络有关的主要技术进行简单介绍。 一、网络命名空间为了支持网络协议栈的多个实例,Linux在网络栈中引入了网络命名空间,这些独立的协议......
  • linux curl p12请求
    ##查看curl版本curl-V##查看curl指令curl--help#--cert证书#--cert-typeTYPECertificatefiletype(DER/PEM/ENG)(SSL)由此可看出linux下curl暂不支持p12证书由p12生成pem证书##生成时如果p12证书有密码,需要输入密码##生成key文件命令opensslpkcs12......
  • 「Linux系列」Shell 流程控制if-else/for循环/While循环/until循环/case语句/跳出循环
    文章目录一、Shell流程控制二、If语句三、For循环四、While循环五、Until循环六、Case语句七、跳出循环break/continue八、相关链接一、Shell流程控制Shell脚本中的流程控制结构允许你根据条件执行不同的代码块,或者重复执行某些代码块。这些结构包括if语句......
  • 【C++】Linux多线程开发
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录3.1线程概述3.2创建线程3.3、线程终止3.4连接已经终止线程3.5线程的分离3.6线程取消3.7线程属性3.8线程同步3.9互斥锁3.10死锁3.11读写锁3.12生产者和消费者模型3.13条件......
  • Linux:网络套接字的认识和基本实现通信
    文章目录UDP和TCP协议网络字节序socket编程常见的接口套接字本篇总结的是对于网络套接字的基本认识UDP和TCP协议在谈网络套接字前,必须先对于UDP和TCP这两个协议有一个基本的认识,这两个协议都是隶属于传输层的协议,并且这两个协议距离用户来说是最近的,所以一般以数据......
  • NCV7351D13R2G收发器芯片中文资料规格书PDF数据手册引脚图参数图片价格特性
    产品概述:NCV7351CAN收发器是控制器区域网络(CAN)协议控制器和物理总线之间的接口,可在12V和24V系统中使用。该收发器为总线提供差分发射功能,向CAN控制器提供差分接收功能。NCV7351是CAN高速收发器系列的新增产品,是NCV734xCAN独立收发器和AMIS42665、AMIS306......
  • Linux打包---Deb包安装和卸载
    包名规则:  package_version-revision_arch.deb dpkg安装信息查看参数:   #dpkg--debug=100:打印安装日志  #dpkg--log=filename:打印日志到文件  #dpkg-x或dpkg-X:将deb包内文件解压出来 安装过程目录/etc/dpkg/dpkg.cfg     ......