8.Linux包管理及shell脚本
前言
我们前面学习一环境变量,也带着大家一起安装了jdk,但在我们安装程序的过程中我们发现确实还是比较麻烦的,我们需要自己找软件的包,然后手动解压缩,再设置环境变量等一系列操作才能安装成功,这节课带大家学习一下 CentOS
中的包管理工具yum
,我们在安装程序的时候就可以非常方便的把上述操作让yum
帮我们完成,然后会带大家入门一下shell脚本的一些语法,我们就可以写一些我自己的脚本了,最后带着大家用我们学习的shell脚本去编写一个redis
一键安装脚本
RPM
rpm
(全称 Redhat Package Manager),是 Red Hat Linux 发行版专门用来管理 Linux 各项套件的程序,由于它遵循 GPL 规则且功能强大方便,因而广受欢迎。逐渐受到其他发行版的采用,RPM 套件管理方式的出现,让 Linux 易于安装,升级,间接提升了 Linux 的适用度
rpm [options]
选项 | 含义 |
---|---|
-a | 所有软件包,常与-q一起使用查询系统中所有软件包 |
-q | 查询 |
-i | 安装 |
-e | 卸载指定软件包 |
-v | 显示rpm执行过程 |
-vv | 详细显示rpm执行过程,便于排错 |
-h | 安装时列出标记 |
--force | 强行置换软件或文件 |
--version | 显示版本信息 |
练习:
- 查询系统安装的jdk列表
rpm -qa | grep jdk
- 使用如下命令下载jdk的rpm包
wget https://repo.huaweicloud.com/java/jdk/8u151-b12/jdk-8u151-linux-x64.rpm
- 安装jdk的rpm包,很明显我们可以使用
-i
参数来安装,但我们还看到rpm的执行过程,此时就可以加上-v
,如果还想看到安装的进度则可以加上-h
参数,这也就是大家在网上看到的rpm -ivh
的由来
rpm -ivh jdk-8u151-linux-x64.rpm
Yum
介绍
-
yum
(全称 Yellow dog Updater, Modified),是一个在Fedora
和RedHat
以及CentOS
中的 Shell 端软件包管理器 -
yum
基于 RPM 包管理,能够从指定的服务器自动下载 RPM 包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软件包,无须繁琐地一次次下载、安装 -
yum
提供了查找、安装、删除某一个、一组甚至全部软件包的命令,而且命令简洁而又好记
其实yum就是依赖rpm,在rpm的基础上做了功能的扩展,如自动解决依赖,所以yum不能脱离rpm单独运行
注:因为我们教程中用的操作系统为CentOS,所以这里的包管理工具就是yum,如果大家是其它操作系统如ubuntu、deepin等可以使用对应操作系统的包管理工具
yum语法
yum的执行需要root用户要拥有root权限的用户
yum [command] [options] [package ...]
- command:要进行的操作命令
- options:选项参数
- package:要安装的包
yum常用命令
命令 | 含义 |
---|---|
yum check-update | 列出所有可更新的软件清单 |
yum update | 更新所有软件 |
yum install <package> | 安装指定的软件 |
yum update <package> | 更新指定的软件 |
yum list | 列出所有可安裝的软件清单 |
yum remove <package> | 删除指定软件包 |
yum search <keyword> | 查找软件包 |
yum clean packages | 清除缓存目录下的软件包 |
yum clean headers | 清除缓存目录下的 headers |
yum clean oldheaders | 清除缓存目录下旧的 headers |
yum clean all | 除缓存目录下的软件包及旧的 headers |
yum makecache | 重新生成缓存 |
yum常用选项
选项 | 含义 |
---|---|
-h | 帮助 |
-y | 当yum执行过程中所有提示全选yes |
-q | 不显示执行过程 |
练习
-
卸载系统自带的
jdk
- 我们可以先使用如下命令查看系统自带的
jdk
rpm -qa | grep jdk
- 我们可以使用
yum remove
卸载我们系统自带的jdk
,由于我们系统上安装的jdk比较多,我们可以直接使用awk
来生成卸载的命令然后执行
rpm -qa | grep jdk | awk '{printf("sudo yum remove %s -y\n",$1)}' > remove.sh && /bin/sh remove.sh && rm -fr remove.sh
- 我们可以先使用如下命令查看系统自带的
-
安装
tree
命令
yum install tree -y
修改yum源
-
我们刚刚在下载
tree
的时候不知道大家有没有感觉到下载的速度很慢,这是因为CentOS是从国外去下载这些软件的 -
我们yum包管理工具是如何知道应该从那里去下载我们要安装的软件及其所需要的依赖呢,这里就有一个yum源,我们可以在
/etc/yum.repos.d
目录中看到 -
在这里我们可以看到很多以
.repo
结尾的文件,这里就存放了yum的软件源地址- CentOS-Base.repo:联网后基础的源,一般都用这个
- CentOS-Media.repo:使用光盘挂载后调用的文件
- CentOS-Vault .repo:最近新版本的加入的老版本的yum源配置
- CentOS-Debuginfo.repo:和内核相关的更新和软件安装
-
所以我们一般联网安装用的就是
CentOS-Base.repo
,我们打开该文件可以看到里面有一些url地址,这些就软件源仓库的地址,我们只需要把这里的地址修改成国内的就可以提高yum的下载速度 -
国内源
-
这里以阿里源为例,使用如下命令下载阿里提供的
CentOS-Base.repo
文件替换系统自带的文件
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
- 生成yum缓存
yum makecache
- 使用yum安装python3测试
yum install python3 -y
Shell脚本
介绍
Shell 脚本(shell script),是一种为 shell 编写的脚本程序,业界所说的 shell 通常都是指 shell 脚本,但大家要知道,shell 和 shell script 是两个不同的概念
Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了
Linux 的 Shell 种类众多,常见的有
- Bourne Shell(sh)
- Bourne Again Shell(bash)
- C Shell(csh)
- K Shell(ksh)
- Z Shell (zsh)
我们可以在/etc/shells
文件中查看本机安装的shell
我们教程中以bash
为主,也就是 Bourne Again Shell,由于易用和免费,Bash 在日常工作中被广泛使用。同时,Bash 也是大多数Linux 系统默认的 Shell,在MacOS10.15之后的系统上,默认的shell为zsh
第一个Shell脚本
- 我们使用
vi/vim
创建一个文件为myshell1.sh
,内容如下
#!/bin/bash
echo "Hello World"
echo "Hello Linux"
#!
告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序,一般情况下,我们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh
,它同样也可以改为 #!/bin/bash
echo命令之前也已经讲过了,其实之前也给大家提过几次shell脚本,只有没有系统的拿来说,其实不难发现,shell脚本就是我们把这些命令放到一个文件中,然后按顺序从上到下今次执行这些命令
- 为其加上可执行权限
chmod +x myshell1.sh
- 执行shell脚本
./myshell.sh
这里写的是目标shell脚本的路径,绝对路径相对路径都可以,如果是相对路径且在当前目录下,请以./
开头表明是当前目录,否则系统会去PATH环境变量中去找这个文件
变量
普通变量
定义变量
我们可以使用变量名=变量值的方式来定义变量
variable_name=variable_value
注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
- 中间不能有空格,可以使用下划线 _。
- 不能使用标点符号。
- 不能使用bash里的关键字
使用变量
使用一个定义过的变量,只要在变量名前面加美元符号即可
#!/bin/bash
myname="lengwen"
echo $myname
echo ${myname}
变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界
#!/bin/bash
skill="java"
echo "I am good at ${skill}script"
如果不给skill变量加花括号,写成echo "I am good at $skillscript"
,解释器就会把$skillscript当成一个变量
只读变量
使用 readonly
命令可以将变量定义为只读变量,只读变量的值不能被改变
#!/bin/bash
mysite="https://kevinlu98.cn"
readonly mysite
mysite="https://www.kevinlu98.cn"
删除变量
使用unset
命令可以删除变量
#!/bin/bash
mysite="https://kevinlu98.cn"
unset mysite
echo my site is $mysite
字符串
字符串是shell编程中最常用最有用的数据类型(不只shell编程中,基本所有编程语言几乎都是如此),在shell编程中,字符串可以用单引号,也可以用双引号,也可以不用引号
- 单引号
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
- 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用
- 双引号
- 双引号里可以有变量
- 双引号里可以出现转义字符
在字符串操作中常见有如下操作
操作 | 语法 |
---|---|
获取字符串长度 | $ |
提取子串 | $ |
数组
数组中可以存放多个值,shell编程中只支持一维数组,初始化时无需定义数组的大小,数组元素的下标由 0 开始
定义数组
Shell 数组用括号来表示,元素用"空格"符号分割开,语法格式如下
array_name=(value1,value2...valuen)
使用数组
读取数组元素值的一般格式是:
${array_name[index]}
关联数组
关联数组的概念与map类似,可以使用任意的字符串、或者整数作为下标来访问数组元素
关联数组使用declare
命令来声明
declare -A array_name
以下实例我们创建一个关联数组 site,并创建不同的键值:
declare -A site=(["google"]="www.google.com" ["kevinlu"]="www.kevinlu98.cn" ["taobao"]="www.taobao.com")
我们也可以先声明一个关联数组,然后再设置键和值:
declare -A site
site["google"]="www.google.com"
site["kevinlu"]="www.kevinlu98.cn"
site["taobao"]="www.taobao.com"
获取数组所有元素
使用 @
或 *
可以获取数组中的所有元素
echo ${site[@]}
echo ${site[*]}
在数组前加一个感叹号 ! 可以获取数组的所有键
echo ${!site[@]}
echo ${!site[*]}
获取数组长度
获取数组长度的方法与获取字符串长度的方法相同
echo ${#site[@]}
echo ${#site[*]}
传参
我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:
$n
:n
代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……$#
:传递到脚本的参数个数$0
:执行的文件名
以下实例我们向脚本传递三个参数,并分别输出
#!/bin/bash
echo "参数个数:$#"
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
流程控制
判断条件
在shell编程中,一般将条件写到[]
里,常用的语法如下表
字符串判断
语法 | 含义 |
---|---|
str1 = str2 | 当两个串有相同内容、长度时为真 |
str1 != str2 | 当串str1和str2不等时为真 |
-n str1 | 当串的长度大于0时为真(串非空) |
-z str1 | 当串的长度为0时为真(空串) |
str1 | 当串str1为非空时为真 |
数字的判断
语法 | 含义 |
---|---|
int1 -eq int2 | 两数相等为真 |
int1 -ne int2 | 两数不等为真 |
int1 -gt int2 | int1大于int2为真 |
int1 -ge int2 | int1大于等于int2为真 |
int1 -lt int2 | int1小于int2为真 |
int1 -le int2 | int1小于等于int2为真 |
文件的判断
语法 | 含义 |
---|---|
-r file | 用户可读为真 |
-e file | 存在则为真 |
-w file | 用户可写为真 |
-x file | 用户可执行为真 |
-d file | 文件为目录为真 |
复杂逻辑判断
语法 | 含义 |
---|---|
-a | 与 |
-o | 或 |
! | 非 |
判断
if 语句语法格式
if condition
then
command1
command2
...
commandN
fi
if else 语法格式
if condition
then
command1
command2
...
commandN
else
command
fi
if else-if else 语法格式
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
read命令
可以从控制台读取输入
read [-p] [tips] var
# -p 指定提示信息
练习:成绩判断
当成绩大于100或小于0时无效,[0,60)输出C,[60,85)输出B,[85,100]输出A
#!/bin/sh
read -p "请输入成绩:" score
if [ $score -gt 100 -o $score -lt 0 ]
then
echo "成绩无效"
exit
fi
if [ $score -ge 85 ]
then
echo A
elif [ $score -ge 60 ]
then
echo B
else
echo C
fi
for循环
与其他编程语言类似,Shell支持for循环,for循环一般格式为:
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
这里的itemN可以是一个数组
While循环
while 循环用于不断执行一系列命令,其语法格式为:
while condition
do
command1
command2
...
commandN
done
练习:
在if练习的基础上循环获取用户输入,输出成绩ABC,直到用户输入exit
#!/bin/sh
while true
do
read -p "请输入成绩:" score
if [ $score = 'exit' ]
then
echo "退出"
exit
fi
if [ $score -gt 100 -o $score -lt 0 ]
then
echo "成绩无效"
continue
fi
if [ $score -ge 85 ]
then
echo A
elif [ $score -ge 60 ]
then
echo B
else
echo C
fi
done
实战:Redis安装脚本
-
手动安装一遍体验redis安装过程:安装步骤
-
下载redis
-
解压
-
进入redis目录执行make 及 make install
#!/bin/sh
redis_file=redis-3.0.0
if [ $# -gt 0 ]
then
redis_file=redis-$1
echo "select verison 3.0.0"
else
echo "no version select,use default 3.0.0"
fi
download_url="http://download.redis.io/releases/${redis_file}.tar.gz"
if [ -e ${redis_file}.tar.gz ]
then
echo "file is exist "
else
echo "downloading ${redis_file} from ${download_url} ..."
wget $download_url
fi
echo $redis_file
if [ -d $redis_file ]
then
echo "dir is exist"
else
echo "decompression ${redis_file}.tar.gz"
tar zxvf ${redis_file}.tar.gz
fi
cd $redis_file/deps && make hiredis linenoise lua && cd ..
make MALLOC=libc
if [ -d /usr/local/redis ]
then
echo "delete old redis"
sudo rm -fr /usr/local/redis
fi
sudo make PREFIX=/usr/local/redis install
小结
今天内容有些多,大家可以好好消化一下,我们只是入门一下linux,方便我们在工作中可以快速使用,所以对shell的要求不是很高,只需要可以写出简单的shell脚本即可