4 shell与安装

tips 重点讲解内容

4.1 yum使用

  1. 引子:
  2. yum类似于开发工具ideaeclipse中的在线插件安装商店
  3. 我们输入一个将要安装的插件名字,进行搜索、安装的过程。

yum概念
yum( Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器。
yum提供了查找、安装、删除某一个、一组甚至全部软件包的命令,而且命令简洁而又好记。
yum原理
shell与安装 - 图1

注意:必须联网 不同的服务通过yum命令连接远程yum源进行查找、下载、安装

使用者权限:管理员
语法

yum [options] [command] [package ...]
  • options:可选,选项包括-h(帮助),-y(当安装过程提示选择全部为”yes”),-q(不显示安装的过程)等等。
  • command:要进行的操作。
  • package操作的对象。

yum常用命令

  • 1.列出所有可更新的软件清单命令:yum check-update
  • 2.更新所有软件命令:yum update
  • 3.仅安装指定的软件命令:yum install
  • 4.仅更新指定的软件命令:yum update
  • 5.列出所有可安裝的软件清单命令:yum list
  • 6.删除软件包命令:yum remove
  • 7.查找软件包 命令:yum search
  • 8.清除缓存命令:
    • yum clean packages: 清除缓存目录下的软件包
    • yum clean headers: 清除缓存目录下的 headers
    • yum clean oldheaders: 清除缓存目录下旧的 headers
    • yum clean, yum clean all (= yum clean packages; yum clean oldheaders) :清除缓存目录下的软件包及旧的headers

      4.1.1 安装tree

      yum -y install tree   //y当安装过程提示选择全部为"yes"
      
      执行效果如下
      注意:第一次在itcast用户执行的时候
      提示我们【需要管理员权限】
      shell与安装 - 图2
      shell与安装 - 图3
      安装完执行tree命令
      tree
      
      shell与安装 - 图4

      4.1.2 移除tree

      yum remove  tree
      
      执行效果如下
      shell与安装 - 图5
      此时,我们在执行tree命令
      tree
      
      执行效果如下
      shell与安装 - 图6
      如上图,由于我们移除了tree,在执行tree命令的时候发现找不到这个命令了。

      4.1.3 yum查找

      利用 yum 的功能,找出以 tom 为开头的软件名称有哪些
      yum list tom*
      
      执行效果如下
      shell与安装 - 图7

      4.1.4 yum源

      概述
      yum需要一个yum库,也就是yum源。
      简单的说,我们安装软件的时候需要下载软件,将很多软件放在一起就是源。软件安装包的来源,所以yum源就是软件安装包来源
      yum源分类
      目前,yum默认使用的是CentOS的yum源,如下
      shell与安装 - 图8
      shell与安装 - 图9
      目前,国内有很多不错的yum源,比如阿里、网易、搜狐等
      安装阿里yum源
      因为默认的yum源服务器在国外,我们在安装软件的时候会受到速度的影响,所以安装国内yum源在下载的时候速度、稳定性会比国外的好很多。
      1) 安装wget
      yum install -y wget
      
      执行效果如下
      shell与安装 - 图10
      shell与安装 - 图11
      安装成功。
      2) 备份/etc/yum.repos.d/CentOS-Base.repo文件
      cd /etc/yum.repos.d/
      mv CentOS-Base.repo CentOS-Base.repo.back
      
      执行效果如下图
      shell与安装 - 图12
      3) 下载阿里云的Centos-7.repo文件
      wget -O CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
      

      注意 上面的url中要卸载Centos-7.repo;而不是Centos-6.repo

执行效果如下图
shell与安装 - 图13
查看下载的阿里云的Centos-6.repo文件

cat CentOS-Base.repo

执行效果如下

# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client.  You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the 
# remarked out baseurl= line instead.
#
#

[base]
name=CentOS-$releasever - Base - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/os/$basearch/
        http://mirrors.aliyuncs.com/centos/$releasever/os/$basearch/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7

#released updates 
[updates]
name=CentOS-$releasever - Updates - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/updates/$basearch/
        http://mirrors.aliyuncs.com/centos/$releasever/updates/$basearch/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7

#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/extras/$basearch/
        http://mirrors.aliyuncs.com/centos/$releasever/extras/$basearch/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7

#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/centosplus/$basearch/
        http://mirrors.aliyuncs.com/centos/$releasever/centosplus/$basearch/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7

#contrib - packages by Centos Users
[contrib]
name=CentOS-$releasever - Contrib - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/contrib/$basearch/
        http://mirrors.aliyuncs.com/centos/$releasever/contrib/$basearch/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7

如上面的命令,之前是【CentOS】,现在是【aliyun】
4) 重新加载yum

yum clean all

清理之前(CentOS)的缓存
执行效果如下
shell与安装 - 图14

yum makecache

就是把服务器的包信息下载到本地电脑缓存起来,makecache建立一个缓存,以后用install时就在缓存中搜索,提高了速度。
执行效果如下
shell与安装 - 图15
如上图,元数据缓存已建立,缓存成功。
5、验证yum源使用

yum search tomcat

执行效果如下
shell与安装 - 图16
如上图所示,我们发现,现在查找软件信息使用了上面的yum缓存。
Loading mirror speeds from cached hostfile(从缓存的主机文件加载镜像速度)

  • base: mirrors.aliyun.com
  • extras: mirrors.aliyun.com
  • updates: mirrors.aliyun.com

    总结 yum -y install 软件包 卸载软件 yum -y remove 软件包 查找软件 yum list * yum源 版本: 比如我们使用的是CentOS7,在下载CentOS-Base.repo的时候要注意它的版本。

4.2 rpm使用

RPM包管理类似于windows下的“添加/删除程序”但是功能却比“添加/删除程序”强大很多

1、rpm介绍
rpm(redhat package manager) 原本是 Red Hat Linux 发行版专门用来管理 Linux 各项套件的程序,由于它遵循 GPL 规则且功能强大方便,因而广受欢迎。逐渐受到其他发行版的采用。RPM 套件管理方式的出现,让 Linux 易于安装,升级,间接提升了 Linux 的适用度。
2、rpm与yum区别
rpm 只能安装已经下载到本地机器上的rpm 包. yum能在线下载并安装rpm包,能更新系统,且还能自动处理包与包之间的依赖问题,这个是rpm 工具所不具备的。
语法如下:

用法: rpm [选项...]

rpm包
shell与安装 - 图17

注意: 以上为扩展名为.rpm的包 可以理解成是Windows中的.exe文件

安装rpm软件包

rpm -ivh 软件全包名

卸载rpm软件包

rpm -e 软件全包名

列出所有安装过的包

rpm -qa

查询软件包信息

rpm -qi 软件全包名

查看文件安装位置

rpm -ql 软件全包名

4.3 shell使用

shell脚本类似于我们在Windows中编写的批处理文件,它的扩展名是.bat,比如我们启动Tomcat(后面的课程我们会详细讲解)的时候经常启动的startup.bat,就是Windows下的批处理文件。
而在Linux中,shell脚本编写的文件是以.sh结尾的。比如Tomcat下我们经常使用startup.sh来启动我们的Tomcat,这个startup.sh文件就是shell编写的。

4.3.1 shell入门

通过简单的学习,我们编写一个简单的入门shell程序。
我们通过前面学习的echo命令,在shell脚本中打印出一句话。

1) 什么是shell
Shell 脚本(shell script),是一种为 shell 编写的脚本程序。
Shell 脚本Shell Script)又称 Shell 命令稿、程序化脚本,是一种计算机程序使用的文本文件,内容由一连串的 shell 命令组成,经由 Unix Shell 直译其内容后运作
shell与安装 - 图18
Shell 被当成是一种脚本语言来设计,其运作方式与解释型语言相当,由 Unix shell 扮演命令行解释器的角色,在读取 shell 脚本之后,依序运行其中的 shell 命令,之后输出结果。利用 shell 脚本可以进行系统管理,文件操作等。
在 Unix 及所有的系统中,如 Linux、FreeBSD 等操作系统,都存在 shell 脚本。依照 Unix shell 的各种不同类型,shell 脚本也有各种不同方言。在 DOS、OS/2、Microsoft Windows 中的批处理文件,跟 shell 脚本有类似的功能。
2) shell环境

java需要虚拟机解释器, 同理 shell脚本也需要解释器

Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。
查看解释器

cat /etc/shells

执行效果如下
shell与安装 - 图19
Linux 的 Shell 种类众多,常见的有:

  • Bourne Shell(/usr/bin/sh或/bin/sh)
  • Bourne Again Shell(/bin/bash)
  • C Shell(/usr/bin/csh)
  • K Shell(/usr/bin/ksh)
  • Shell for Root(/sbin/sh)
  • 等等……

我们当前课程使用的是 Bash,也就是 Bourne Again Shell,由于易用和免费,Bash 在日常工作中被广泛使用。同时,Bash 也是大多数Linux 系统默认的 Shell
3) 编写第一个shell
现在,我们打开文本编辑器(我们也可以使用 vi/vim 命令来创建文件),新建一个文件 czbk.sh,扩展名为 sh(sh代表shell):

#!/bin/bash  --- 指定脚本解释器
echo "你好,传智播客 !"

//写shell的习惯 第一行指定解释器
//文件是sh为后缀名
//括号成对书写
//注释的时候尽量不用中文注释。不友好。
//[] 括号两端要要有空格。 [ neirong ]
//习惯代码索引,增加阅读性
//写语句的时候,尽量写全了,比如if。。。
1、创建sh文件**

vim czbk.sh

2、编写并保存
shell与安装 - 图20
3、查看czbk.sh文件

ls -l

shell与安装 - 图21
如上图,我们发现刚刚编写的czbk.sh文件的的权限是【-rw-rw-r—】,通过我们之前学过的知识,我们发现这个文件并没有执行的权限
我们需要将czbk.sh文件设置下它的执行权限【x】,如果不设置有执行权限,当前的文件不具备文件执行的能力。
通过chmod设置执行权限

chmod +x ./czbk.sh

执行效果如下
shell与安装 - 图22
我们发现,czbk.sh拥有了【x】执行权限
下面,我们就开始执行czbk.sh
4、执行czbk.sh文件 —- bash a.sh0

./czbk.sh

执行效果如下:
shell与安装 - 图23
如上图,我们刚刚编写的shell在执行的时候正常打印出来了,说明czbk.sh具备执行的能力

注意: #! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。 echo 命令用于向窗口输出文本。

4.3.2 shell注释

引子:
在Java SE课程中,我们也学习了注释
比如单行注释我们使用双斜杠//
   多行注释我们使用/**开头表示注释多行
而在shell编程中,我们同样也要有注释,注释掉程序中不用的脚本

1、单行注释
# 开头的行就是注释,会被解释器忽略。
通过每一行加一个 # 号设置多行注释,如下:

#--------------------------------------------
# 这是一个注释
#--------------------------------------------
##### 开始 #####
#
#
# 这里可以添加脚本描述信息
# 
#
##### 结束  #####

如果在开发过程中,遇到大段的代码需要临时注释起来,过一会儿又取消注释,怎么办呢?
每一行加个#符号太费力了,此时,我们可以通过EOF进行多行注释,如下:
2、多行注释
多行注释还可以使用以下格式:

:<<EOF
注释内容...
注释内容...
注释内容...
EOF

EOF 也可以使用其他符号:

:<<'
注释内容...
注释内容...
注释内容...
'
:<<!
注释内容...
注释内容...
注释内容...
!

总结: 我们将在下面的小章节中使用注释,查看注释效果

4.3.3 shell变量

引子:
这里的变量我们可以理解为我们在Java SE阶段定义的变量,比如在SE中我定义一个字符串类型的变量使用String stringStr="";
注意:下面的演示我们还是继续沿用test-shell.sh进行测试

1、定义变量:

variable_name="czbk"

变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:

  • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
  • 中间不能有空格,可以使用下划线(_)。
  • 不能使用标点符号。
  • 不能使用bash里的关键字(可用help命令查看保留关键字)。

有效的 Shell 变量名示例如下:

RUNOOB
LD_LIBRARY_PATH
_var
var2

无效的变量命名:

?var=123
user*name=runoob

2、使用变量
使用一个定义过的变量,只要在变量名前面加美元符号即可,如:

variable_name="czbk"
echo $variable_name
echo ${variable_name}

执行效果如下
shell与安装 - 图24
变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:

echo "I am good at ${shell-t}Script"

通过上面的脚本我们发现,如果不给shell-t变量加花括号,写成echo “I am good at shell与安装 - 图25shell-tScript当成一个变量,由于我们前面没有定义shell-t变量,那么解释器执行执行的结果自然就为空了。这里我们推荐给所有变量加上花括号,这也是一个好的编程习惯。
已定义的变量,可以被重新定义,如:

your_name="tom"
echo $your_name
your_name="frank"
echo $your_name

执行效果如下图
shell与安装 - 图26
这样写是合法的,但注意,第二次赋值的时候不能写shell与安装 - 图27
3、只读变量

这里的只读变量其实有点类似于我们在java se阶段课程中定义的final变量,即在程序的上下文中不允许被程序修改

使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
下面的例子尝试更改只读变量,结果报错:

#!/bin/bash
myUrl="https://www.baidu.com"
readonly myUrl
myUrl="https://cn.bing.com/"

执行效果如下图
shell与安装 - 图28
4、删除变量
使用 unset 命令可以删除变量。语法:

unset variable_name

变量被删除后不能再次使用。unset 命令不能删除只读变量。
示例如下

#!/bin/sh
myUrl="https://www.baidu.com"
unset myUrl
echo $myUrl

执行效果如下图
shell与安装 - 图29
如上面的shell脚本,我们定义了一个myUrl变量,通过unset删除这个变量,然后通过echo进行输出,结果是就是为空,没有任何的结果输出。


Shell 字符串

字符串是shell编程中最常用也是最有用的数据类型,字符串可以用单引号,也可以用双引号,也可以不用引号,正如我们开篇提到的,在Java SE中我们定义一个字符串可以通过Stirng  stringStr=“abc" 双引号的形式进行定义,而在shel中也是可以的。

单引号

str='this is a string variable'

单引号字符串的限制:

  • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
  • 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。

双引号

your_name='frank'
str="Hello,  \"$your_name\"! \n"
echo -e $str

输出结果为:
shell与安装 - 图30
双引号的优点:

  • 双引号里可以有变量
  • 双引号里可以出现转义字符

拼接字符串

your_name="frank"
# 使用双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting  $greeting_1

输出结果为:
shell与安装 - 图31
获取字符串长度

string="czbk"
echo ${#string}

输出结果:4.表示长度为4
shell与安装 - 图32
提取字符串
以下实例从字符串第 2 个字符开始截取 4 个字符:

string="abcdefghijklmn"
echo ${string:1:4}

执行效果如下
shell与安装 - 图33
输出为【bcde】,通过截取我们发现,它的下标和我们在java中的读取方式是一样的,下标也是从0开始。

4.3.4 shell数组

这里的数组和我们在Java SE阶段的数组结果(或是性质)是一样的,只是定义的过程大同小异

bash支持一维数组(不支持多维数组),并且没有限定数组的大小。
定义数组
在 Shell 中,用括号来表示数组,数组元素用”空格”符号分割开。如下:

数组名=(值1 值2 ... 值n)

例如:

array_name=(value0 value1 value2 value3)

或者

array_name=(
value0
value1
value2
value3
)

通过下标定义数组中的其中一个元素:

array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen

可以不使用连续的下标,而且下标的范围没有限制。
读取数组
读取数组元素值的一般格式是:

${数组名[下标]}

例如:

valuen=${array_name[n]}

使用 @ 符号可以获取数组中的所有元素,例如:

echo ${array_name[@]}

获取数组的长度
获取数组长度的方法与获取字符串长度的方法相同,例如:

# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}

下面,我们通过一个例子,定义数组、提取数组元素的例子来验证下

#! /bin/bash
g=(a b c d e f)
echo "数组下标为2的数据为:" ${g[2]}
echo  "数组所有数据为:"  ${#g[@]}
echo  "数组所有数据为:"   ${#g[*]}

如下
shell与安装 - 图34
执行效果如下:
shell与安装 - 图35

4.3.5 shell运算符

我们在前面课程中学习Java SE中也学到了运算符,比如算术、关系、布尔等,而在sehll编程中同样也有运算符,虽然表达的方式不一样,但是最终的目的都是一样的,都是为了解决编程中现存问题

Shell 和其他编程一样,支持包括:算术、关系、布尔、字符串等运算符。
原生 bash 不支持 简单的数学运算,但是可以通过其他命令来实现,例如expr。
expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
例如,两个数相加,我们还是利用上面的例子test-shell.sh
1、算数运算符

val=`expr 2 + 2`
echo "相加之后的结果为:" $val

执行效果如下
shell与安装 - 图36
注意:
表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2。
完整的表达式要被 ` 包含,注意不是单引号。
下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
+ 加法 expr $a + $b
结果为 30。
- 减法 expr $a - $b
结果为 -10。
* 乘法 expr $a \\* $b
结果为 200。
/ 除法 expr $b / $a
结果为 2。
% 取余 expr $b % $a
结果为 0。
= 赋值 a=$b 将把变量 b 的值赋给 a。
== 相等。用于比较两个数字,相同则返回 true。 [ $a == $b ] 返回 false。
!= 不相等。用于比较两个数字,不相同则返回 true。 [ $a != $b ] 返回 true。

注意:条件表达式要放在方括号之间,并且要有空格,例如: [shell与安装 - 图37b] 是错误的,必须写成 [ $a == $b ]
下面是运算符shell脚本(还是采用之前的例子test-shell.sh )w

#! /bin/bash
#g=(a b c d e f)
#echo "数组下标为2的数据为:" ${g[2]}
#echo  "数组所有数据为:"  ${#g[@]}
#echo  "数组所有数据为:"   ${#g[*]}
:<<EOF
val= `expr 2 + 2`
echo "相加之后的结果为:" $val
EOF
a=4
b=20
echo “加法运算”  `expr $a + $b`
echo “减法运算”  `expr $a - $b`
echo “乘法运算,注意*号前面需要反斜杠” ` expr $a \* $b`
echo “除法运算”  `expr  $b / $a`
((a++))
echo "a = $a"
c=$((a + b)) 
d=$[a + b]
echo "c = $c"
echo "d = $d"

上面的shell命令#开头的为单行注释
:<<EOF 开头和EOF结尾的为多行注释
执行效果如下
shell与安装 - 图38
2、字符串运算符
下表列出了常用的字符串运算符,假定变量 a 为 “abc”,变量 b 为 “efg”:

运算符 说明 举例
= 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
!= 检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。
-z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
-n 检测字符串长度是否为0,不为0返回 true。 [ -n “$a” ] 返回 true。
$ 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。

字符串运算符实例如下(还是采用之前的例子test-shell.sh ):

a="abc"
b="efg"
if [ $a = $b ]
then
   echo "$a = $b : a 等于 b"
else
   echo "$a = $b: a 不等于 b"
fi
if [ $a != $b ]
then
   echo "$a != $b : a 不等于 b"
else
   echo "$a != $b: a 等于 b"
fi

执行效果如下
shell与安装 - 图39
3、关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
-eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。
-ne 检测两个数是否不相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
-gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。
-lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。
-ge 检测左边的数是否大于等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。
-le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。

关系运算符(还是采用之前的例子test-shell.sh )

a=10
b=20
if [ $a -eq $b ]
then
   echo "$a -eq $b : a 等于 b"
else
   echo "$a -eq $b: a 不等于 b"
fi
if [ $a -ne $b ]
then
   echo "$a -ne $b: a 不等于 b"
else
   echo "$a -ne $b : a 等于 b"
fi
if [ $a -gt $b ]
then
   echo "$a -gt $b: a 大于 b"
else
   echo "$a -gt $b: a 不大于 b"
fi
if [ $a -lt $b ]
then
   echo "$a -lt $b: a 小于 b"
else
   echo "$a -lt $b: a 不小于 b"
fi
if [ $a -ge $b ]
then
   echo "$a -ge $b: a 大于或等于 b"
else
   echo "$a -ge $b: a 小于 b"
fi
if [ $a -le $b ]
then
   echo "$a -le $b: a 小于或等于 b"
else
   echo "$a -le $b: a 大于 b"
fi

执行效果如下:
shell与安装 - 图40
4、布尔运算符
下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
-o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。

布尔运算符实例如下(还是采用之前的例子test-shell.sh ):

a=10
b=20
if [ $a != $b ]
then
   echo "$a != $b : a 不等于 b"
else
   echo "$a == $b: a 等于 b"
fi
if [ $a -lt 100 -a $b -gt 15 ]
then
   echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
   echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi
if [ $a -lt 100 -o $b -gt 100 ]
then
   echo "$a 小于 100 或 $b 大于 100 : 返回 true"
else
   echo "$a 小于 100 或 $b 大于 100 : 返回 false"
fi
if [ $a -lt 5 -o $b -gt 100 ]
then
   echo "$a 小于 5 或 $b 大于 100 : 返回 true"
else
   echo "$a 小于 5 或 $b 大于 100 : 返回 false"
fi

执行效果如下
shell与安装 - 图41
5、逻辑运算符
假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
&& 逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false
|| 逻辑的 OR [[ $a -lt 100 || $b -gt 100 ]] 返回 true

逻辑运算符实例如下(还是采用之前的例子test-shell.sh ):

a=10
b=20
if [[ $a -lt 100 && $b -gt 100 ]]
then
   echo "返回 true"
else
   echo "返回 false"
fi
if [[ $a -lt 100 || $b -gt 100 ]]
then
   echo "返回 true"
else
   echo "返回 false"
fi

执行效果如下
shell与安装 - 图42

4.3.6 shell流程控制

在前面的Java SE课程中,我们学习了很多的流程控制语句,比如有if-else、if else-if else、switch、for、while等语句;
在shell编程中,我们同样也有这些流程控制,只是语法和java SE有所区别,但是目的是一样的。

1、if 语句:
主要用于判断,相当于java se中的if,我们还是采用之前的例子test-shell.sh

if condition
then
    command1 
    command2
    ...
    commandN 
fi

比如,我们现在通过前面学习的知识查找一个进程,如果进程存在就打印true

if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi

注意 末尾的fi就是if倒过来拼写

执行效果如下
shell与安装 - 图43
2、if else 语句:
主要用于判断,相当于java se中的if else,我们还是采用之前的例子test-shell.sh。

if condition
then
    command1 
    command2
    ...
    commandN
else
    command
fi

上接上面的例子,如果找不到sshAAA(此处可以随便输入一个)进程,我们就打印false

if [ $(ps -ef | grep -c "sshAAA") -gt 1 ]; then echo "true";  else echo "false"; fi

执行效果如下
shell与安装 - 图44
3、if else-if else 语句:
主要用于判断,相当于java se中的if else-if else

if condition1
then
    command1
elif condition2 
then 
    command2
else
    commandN
fi

以下实例判断两个变量是否相等
我们继续使用上面的例子(test-shell.sh )

a=10
b=20
if [ $a == $b ]
then
   echo "a 等于 b"
elif [ $a -gt $b ]
then
   echo "a 大于 b"
elif [ $a -lt $b ]
then
   echo "a 小于 b"
else
   echo "没有符合的条件"
fi

执行效果如下
shell与安装 - 图45
4、for 循环
主要用于循环,相当于java se中的for循环,我们还是采用之前的例子test-shell.sh
for循环格式为

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done

顺序输出当前列表中的字母:

for loop in A B C D E F G 
do
    echo "顺序输出字母为: $loop"
done

执行效果如下
shell与安装 - 图46
5、while循环
主要用于循环,相当于java se中的while循环
while循环用于不断执行一系列命令,也用于从输入文件中读取数据
语法格式为

while condition
do
    command
done

以下是一个基本的while循环,测试条件是:如果int小于等于10,那么条件返回真。int从0开始,每次循环处理时,int加1。
还是采用之前的例子test-shell.sh

#!/bin/bash
int=1
while(( $int<=10 ))
do
    echo "输出的值为:"$int
    let "int++"
done

执行效果如下图
shell与安装 - 图47
6、case … esac语句
主要用于分支条件选择,相当于java se中的switch case循环
case … esac 与其他语言中的 switch … case 语句类似,是一种多分枝选择结构,每个 case 分支用右圆括号开始,用两个分号 ;; 表示 break,即执行结束,跳出整个 case … esac 语句,esac(就是 case 反过来)作为结束标记。
还是采用之前的例子test-shell.sh
case … esac 语法格式如下:

case 值 in
模式1)
    command1
    command2
    command3
    ;;
模式2)
    command1
    command2
    command3
    ;;
*)
    command1
    command2
    command3
    ;;
esac

case 后为取值,值可以为变量或常数。
值后为关键字 in,接下来是匹配的各种模式,每一模式最后必须以右括号结束,模式支持正则表达式。
下面通过v的值进行case—esac

v="czbk"
case "$v" in
   "czbk") echo "传智播客"
   ;;
   "baidu") echo "baidu 搜索"
   ;;
   "google") echo "google 搜索"
   ;;
esac

执行效果如下
shell与安装 - 图48

4.3.7 shell函数

我们将要学习的shell函数,我们可以理解成在Java SE阶段我们学习的方法,它和shell函数的作用是一样的。

函数语法如下:

[ function ] funname [()]
{
    action;
    [return int;]
}

注意:

  • 1、可以使用function fun() 定义函数,也可以直接fun() 定义,不带任何参数。
  • 2、函数参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255

下面我们将定义一个函数,并发生函数调用
还是采用之前的例子test-shell.sh

#!/bin/bash
czbk(){
    echo "这是第一个函数!"
}
echo "-----这里是函数开始执行-----"
czbk
echo "-----这里是函数执行完毕-----"

执行效果如下图
shell与安装 - 图49
下面,我们定义一个带有return语句的函数:

function czbk(){
    echo "对输入的两个数字进行相加运算..."
    echo "输入第一个数字: "
    read aNum
    echo "输入第二个数字: "
    read anotherNum
    echo "两个数字分别为 $aNum 和 $anotherNum !"
    return $(($aNum+$anotherNum))
}
czbk
echo "输入的两个数字之和为 $? !"

注意: 函数返回值在调用该函数后通过 $? 来获得。 注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。