shell脚本基础!

一.shell脚本概述

1.Shell脚本的概念

将要执行的命令按顺序保存到一个文本文件

给该文件可执行权限

可结合各种Shell控制语句以完成更复杂的操作

2.Shell脚本应用场景

重复性操作

交互性任务

批量事务处理

服务运行状态监控

定时任务执行

3.Shell的作用

命令解释器,翻译官

介于系统内核与用户之间,复制解释命令行

4.编写shell脚本

使用vim文件编辑器
每行一条linux命令,按执行顺序一次编写

vim first.sh
在这里插入图片描述
多行注释也可以用下列方式表示
在这里插入图片描述
在这里插入图片描述

给脚本权限

chmod +x first.sh

执行脚本

[root@localhost ~]# ./first.sh
hello world!!
[root@localhost ~]# /root/first.sh
hello world!!
[root@localhost ~]# bash first.sh
hello world!!
[root@localhost ~]# sh first.sh
hello world!!
[root@localhost ~]# 

说明

在没有权限的情况下使用bash,sh执行脚本

bash sh 是在新开的shell环境执行,执行完返回

bash 与sh ksh比较
bash优点 更高级 可以看到当前用户 支持快捷键 可以补全命令

bash -x 每一行检测调试
在这里插入图片描述

bash -n 只检查语法错误 检查指定哪行出错

在这里插入图片描述

5.管道和重定向

(1)管道操作

管道操作作为不同命令之间的协同工作提供了一种机制,位于管道符号“|”左侧的命令输出的结果,将作为右侧命令的输入(出来对象),同一行命令中可以使用多个管道。

[root@localhost ~]# df -hT
文件系统                类型      容量  已用  可用 已用% 挂载点
/dev/mapper/centos-root xfs        50G  5.3G   45G   11% /
devtmpfs                devtmpfs  894M     0  894M    0% /dev
tmpfs                   tmpfs     910M     0  910M    0% /dev/shm
tmpfs                   tmpfs     910M   11M  900M    2% /run
tmpfs                   tmpfs     910M     0  910M    0% /sys/fs/cgroup
/dev/sda1               xfs      1014M  179M  836M   18% /boot
/dev/mapper/centos-home xfs       247G   38M  247G    1% /home
tmpfs                   tmpfs     182M  8.0K  182M    1% /run/user/42
tmpfs                   tmpfs     182M   52K  182M    1% /run/user/0
/dev/sr0                iso9660   4.3G  4.3G     0  100% /run/media/root/CentOS 7 x86_64


[root@localhost ~]# df -hT | grep "/$" |awk '{print $6}'
11%
[root@localhost ~]# 

(2)重定向操作

交互式硬件设备

标准输入:从键盘输入,设定键盘为输入设备

标准输出:通过显示器输出到屏幕

标准错误:当我执行一个命令时,显示器会把错误信息输出到屏幕

在这里插入图片描述

重定向操作

在这里插入图片描述

重定向输出 >是覆盖 ;>>是追加 ;1>正确输出

[root@localhost ~]# echo 1234 > 11.txt
[root@localhost ~]# cat 11.txt
1234
[root@localhost ~]# echo 1234 >> 11.txt
[root@localhost ~]# cat 11.txt
1234
1234
[root@localhost ~]# echo 1234 1> 11.txt
[root@localhost ~]# cat 11.txt
1234
[root@localhost ~]# 

错误输入用2> :错误输入追加用2>>

[root@localhost ~]# ls
11.txt  1234.txt  anaconda-ks.cfg  expect.sh  initial-setup-ks.cfg  公共  模板  视频  图片  文档  下载  音乐  桌面
[root@localhost ~]# ls xx
ls: 无法访问xx: 没有那个文件或目录
[root@localhost ~]# ls xx > 2.txt
ls: 无法访问xx: 没有那个文件或目录
[root@localhost ~]# ls xx >> 2.txt
ls: 无法访问xx: 没有那个文件或目录
[root@localhost ~]# cat 2.txt
[root@localhost ~]# ls xx 2> 2.txt
[root@localhost ~]# cat 2.txt
ls: 无法访问xx: 没有那个文件或目录
[root@localhost ~]# ls xx 2>> 2.txt
[root@localhost ~]# cat 2.txt
ls: 无法访问xx: 没有那个文件或目录
ls: 无法访问xx: 没有那个文件或目录
[root@localhost ~]# 

有正确输入也有错误输入

[root@localhost ~]# ls xx 11.txt
ls: 无法访问xx: 没有那个文件或目录
11.txt
[root@localhost ~]# ls xx 11.txt > 3.txt
ls: 无法访问xx: 没有那个文件或目录
[root@localhost ~]# cat 3.txt
11.txt
[root@localhost ~]# ls xx 11.txt 2> 3.txt >4.txt
[root@localhost ~]# cat 3.txt
ls: 无法访问xx: 没有那个文件或目录
[root@localhost ~]# cat 4.txt
11.txt
[root@localhost ~]# 

输出不显示可以用混合输出 &> /dev/null

[root@localhost ~]# ls xx
ls: 无法访问xx: 没有那个文件或目录
[root@localhost ~]# ls xx &> /dev/null
[root@localhost ~]# 

<是读取数据

[root@localhost ~]# cat 11.txt
1234
[root@localhost ~]# cat < 11.txt
1234
[root@localhost ~]# 

二.shell脚本变量

1.自定义变量

(1)定义一个新变量

定义新变量并查看变量值

[root@localhost ~]# a=10
[root@localhost ~]# echo $a
10
[root@localhost ~]# a=114
[root@localhost ~]# echo $a
114
[root@localhost ~]# A=lisa
[root@localhost ~]# echo $A
lis


unset 取消变量

[root@localhost ~]# unset a
[root@localhost ~]# echo $a

[root@localhost ~]# 

set 可以查看所有的变量

[root@localhost ~]# AA=wangwu
[root@localhost ~]# set | grep wangwu
AA=wangwu
[root@localhost ~]# 

自定义变量只作用于当前环境

[root@localhost ~]# AA=wangwu
[root@localhost ~]# echo $AA
wangwu
[root@localhost ~]# bash
[root@localhost ~]# echo $AA

[root@localhost ~]# 

(2)赋值时使用引号

单引号:允许通过$符号引用其他变量值

双引号:禁止引用其他变量值,$视为普通字符

反撇号:命令替换,提取命令执行后的输出结果


[root@localhost ~]# a=10
[root@localhost ~]# echo "$a"
10

[root@localhost ~]# echo '$a'
$a

[root@localhost ~]# echo \$a
$a

[root@localhost ~]# echo `date`
20210614日 星期一 22:05:22 CST

[root@localhost ~]# a=$(date)
[root@localhost ~]# echo $a
20210614日 星期一 22:22:18 CST

[root@localhost ~]# echo $(rpm -qf $(which rz))
lrzsz-0.12.20-36.el7.x86_64
[root@localhost ~]# rpm -ql $(rpm -qf $(which rz))
/usr/bin/rb
/usr/bin/rx
/usr/bin/rz
/usr/bin/sb
/usr/bin/sx
/usr/bin/sz
/usr/share/locale/de/LC_MESSAGES/lrzsz.mo
/usr/share/man/man1/rz.1.gz
/usr/share/man/man1/sz.1.gz
[root@localhost ~]# 

(3)声明变量是整数类型的变量

[root@localhost ~]# declare -i int=10
[root@localhost ~]# echo $int
10
[root@localhost ~]# int=20
[root@localhost ~]# echo $int
20
[root@localhost ~]# int=xuxu
[root@localhost ~]# echo $int
0
[root@localhost ~]# 

(4)定义变量为只读变量

[root@localhost ~]# a=wangwu
[root@localhost ~]# readonly a

[root@localhost ~]# echo $a
wangwu

[root@localhost ~]# a=lisi
bash: a: 只读变量
[root@localhost ~]# 
[root@localhost ~]# unset a
bash: unset: a: 无法反设定: 只读 variable


(5)read命令也可以定义赋值变量

[root@localhost ~]# read name
zhangsan                           //这里会等待你输入变量
[root@localhost ~]# echo $name
zhangsan
[root@localhost ~]# 

选项说明

-p 会提示输入
-n 指定最大输入的变量数
-s 私密静默,输入时不显示
在这里插入图片描述
在这里插入图片描述

(6)数值变量的运算

整数变量的运算

expr命令

expr 变量 运算符 变量
expr只识别整数,不是整数会进行取整

常用运算符

加法运算:+
减法运算:-
乘法运算:\ * 乘法需要用转义符
除法运算:/
求模(取余)运算:%

[root@localhost ~]# expr 1 + 1
2
[root@localhost ~]# expr 8 - 2
6
[root@localhost ~]# expr 4 * 3
expr: 语法错误
[root@localhost ~]# expr 4 \* 3
12
[root@localhost ~]# expr 10 / 3
3
[root@localhost ~]# expr 10 % 3
1
[root@localhost ~]# 

[root@localhost ~]# a=10
[root@localhost ~]# b=3
[root@localhost ~]# expr $a + $b
13
[root@localhost ~]# expr $a - $b
7
[root@localhost ~]# expr $a \* $b
30
[root@localhost ~]# expr $a / $b
3
[root@localhost ~]# expr $a % $b
1
[root@localhost ~]# 

[root@localhost ~]# echo $[2 + 2]
4
[root@localhost ~]# echo $[2 / 2]
1
[root@localhost ~]# echo $[2 % 2]
0
[root@localhost ~]# echo $[a + b]
13
[root@localhost ~]# echo $[a % b]
1
[root@localhost ~]# 

let命令

a++ 表示 a=a+1
a-- 表示 a=a-1

[root@localhost ~]# a=10
[root@localhost ~]# echo $a
10
[root@localhost ~]# let a++
[root@localhost ~]# echo $a
11
[root@localhost ~]# let a--
[root@localhost ~]# echo $a
10
[root@localhost ~]# echo $[a++]
10
[root@localhost ~]# echo $a
11
[root@localhost ~]# echo $[++a]
12
[root@localhost ~]# echo $a
12
[root@localhost ~]# 

bc计算器

[root@localhost ~]# bc                         //单独用bc是交互式页面
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
2.6+8.1
10.7
5.8*3
17.4

quit
[root@localhost ~]# 

[root@localhost ~]# echo "2.5+8.4" | bc
10.9
[root@localhost ~]# echo "scale=3;10/3" | bc   //区小数点后几位
3.333
[root@localhost ~]# echo $[2**8]               //计算次方
256
[root@localhost ~]# let a=2**8
[root@localhost ~]# echo $a
256
[root@localhost ~]# echo "2^8" | bc           //bc计算器计算次方
256
[root@localhost ~]# 

2.特殊变量

(1)环境变量

env查看所有环境变量
查看单个
echo $PWD

自定义变量只作用于当前环境,要使其作用于全局要写入环境变量

aa=10
写入环境变量
vim /etc/profile
最后一行加入
export aa=10

vim /etc/profile
在这里插入图片描述


[root@localhost ~]# source /etc/profile   //重新读入配置文件
[root@localhost ~]# echo $aa
10
[root@localhost ~]# bash
[root@localhost ~]# echo $aa
10
[root@localhost ~]# 

export命令
为了使用户定义的变量在所有的子Shell环境中能够继续使用,减少重复设置工作,可以通过内部命令export将指定的变量导出为全局变量。用户可以同时指定多个变量名称作为参数(无须使用“$”符号),变量名之间以空格分隔,但是export命令只是临时的。

使用export 导出全局变量的同时,也可以为变量进行赋值,这样在新定义全局变量时就不需要提前进行赋值了
env查看用户当前环境变量export ABC=123
再次env就能看到了
export -n ABC取消定义的全局变量变成局部变量


[root@localhost ~]# bb=20
[root@localhost ~]# echo $bb
20
[root@localhost ~]# export bb     
[root@localhost ~]# env | grep bb
bb=20
[root@localhost ~]# 

查看当前bash层级

[root@localhost ~]# echo $SHLVL
9
[root@localhost ~]# 

(2)位置变量

第一个位置变量为$1,第二个位置变量为$2,以此类推

vim test.sh

在这里插入图片描述

[root@localhost ~]# bash test.sh 8 6
14

[root@localhost ~]# bash test.sh 3 9
12
[root@localhost ~]# 

(3)预定义变量

预定义变量是由Bash程序预先定义好的一类特殊变量,用户只能使用预定义变量,而不能创建新的预定义变量,也不能直接为预定义变量赋值。预定义变量使用“$”符号和另一个符号组合表示。

$? 上一条命令的结果 为0成功 非0不成功

$# 表示命令行中位置变量的个数

$$ 表示返回当前进程的进程号

$! 返回最后一个后台进程的进程号

$* 表示所有位置参数的内容,这些内容当做一个整体

$@ 显示全部内容 个体

$0 表示当前执行的脚本或程序的名称


[root@localhost ~]# ls
11.txt  1234.txt  2.txt  3.txt  4.txt  anaconda-ks.cfg  expect.sh  initial-setup-ks.cfg  公共  模板  视频  图片  文档  下载  音乐  桌面
[root@localhost ~]# echo $?
0
[root@localhost ~]# ls xx
ls: 无法访问xx: 没有那个文件或目录
[root@localhost ~]# echo $?
2
[root@localhost ~]# echo $#
0
[root@localhost ~]# echo $*

[root@localhost ~]# echo $$
36682
[root@localhost ~]# echo $@

[root@localhost ~]# echo $!

[root@localhost ~]# sleep 100 &
[1] 38654
[root@localhost ~]# echo $!
38654

三.shell编程之条件语句

1.条件测试

(1)文件测试

文件测试指的是根据给定的路径名称,判断对应的是文件还是目录,或者判断文件是否存在,是否可读、可写、可执行等

选项:(主要是defrwx)

-d:测试是否为目录(Directory)

-e:测试目录或文件是否存在(Exist)

-f:测试是否为文件(File)

-L:测试是否为链接文件

-b:测试是否为设备文件

-c:测试是否为字符设备文件

-r:测试当前用户是否有权限读取(Read)

-w:测试当前用户是否有权限写入(Write)

-x:测试是否设置有可执行(Excute)权限

-s:测试存在且文件大小为空

[root@localhost ~]# [ -d /etc ] && echo y || echo n
y
[root@localhost ~]# [ -d /xxx ] && echo y || echo n
n
[root@localhost ~]# [ -f /xxx ] && echo y || echo n
n
[root@localhost ~]# [ -f /etc ] && echo y || echo n
n
[root@localhost ~]# [ -e /etc ] && echo y || echo n
y
[root@localhost ~]# [ -e /etc/xxx ] && echo y || echo n
n
[root@localhost ~]# [ -w /etc/ ] && echo y || echo n
y
[root@localhost ~]# 

(2)整数值比较

整数值比较指的是根据给定的两个整数值,判断第一个数与第二个数的关系,如是否大于、等于、小于第二个数,实际应用非常广泛

例如用来判断已登录用户数量、开启进程数、磁盘使用率是否超标,以及软件版本号是否符合要求等

操作选项:

-eq:第一个数等于(Equal)第二个数。

-ne:第一个数不等于(Not Equal)第二个数。

-gt:第一个数大于(Greater Than)第二个数。

-lt:第一个数小于(Lesser Than)第二个数。

-le:第一个数小于或等于(Lesser or Equal)第二个数。

-ge:第一个数大于或等于(Greater or Equal)第二个数

[root@localhost ~]# [ 2 -eq 4 ] && echo y || echo n
n
[root@localhost ~]# [ 2 -gt 4 ] && echo y || echo n
n
[root@localhost ~]# [ 2 -lt 4 ] && echo y || echo n
y
[root@localhost ~]# [ 2 -eq 2 ] && echo y || echo n
y
[root@localhost ~]# [ 2 -ne 2 ] && echo y || echo n
n
[root@localhost ~]# [ 2 -ge 2 ] && echo y || echo n
y
[root@localhost ~]# [ 2 -le 2 ] && echo y || echo n
y
[root@localhost ~]# 

(3)字符串比较

字符串你叫常用的操作选项

=:第一个字符串与第二个字符串相同

!=:第一个字符串与第二个字符串不相同,其中" ! “ 符号表示取反

-z:检查字符串是否为空,对于未定义或赋予空值的变量视为空串

-n:检测字符串是否为非空


[root@localhost ~]# test a == b
[root@localhost ~]# echo $?
1
[root@localhost ~]# test a != b
[root@localhost ~]# echo $?
0
[root@localhost ~]# 



[root@localhost ~]# a=xuxu 

[root@localhost ~]# echo $a
xuxu
[root@localhost ~]# [ -z $a ] && echo y || echo n
n
[root@localhost ~]# [ -n $a ] && echo y || echo n
y
[root@localhost ~]# [ -n xx ] && echo y || echo n
y
[root@localhost ~]# 


[root@localhost ~]# [ a == b ] && echo y || echo n
n
[root@localhost ~]# [ a != b ] && echo y || echo n
y
[root@localhost ~]# 


[root@localhost ~]# a=
[root@localhost ~]# [ -z $a ] && echo y || echo n
y
[root@localhost ~]# [ -n $a ] && echo y || echo n
y
[root@localhost ~]# [ -z "$a" ] && echo y || echo n
y
[root@localhost ~]# [ -n "$a" ] && echo y || echo n
n
[root@localhost ~]# 


(4)逻辑测试

常用的测试操作符

-a或&&:逻辑与,“而且”的意思

-o或||:逻辑或,“或者”的意思·

!:逻辑否

[root@localhost ~]# ls
11.txt  1234.txt  2.txt  3.txt  4.txt  anaconda-ks.cfg  expect.sh  initial-setup-ks.cfg  公共  模板  视频  图片  文档  下载  音乐  桌面
[root@localhost ~]# ls ; date
11.txt  1234.txt  2.txt  3.txt  4.txt  anaconda-ks.cfg  expect.sh  initial-setup-ks.cfg  公共  模板  视频  图片  文档  下载  音乐  桌面
20210615日 星期二 10:56:42 CST
[root@localhost ~]# ls xx ; date
ls: 无法访问xx: 没有那个文件或目录
20210615日 星期二 10:56:50 CST
[root@localhost ~]# ls xx && date
ls: 无法访问xx: 没有那个文件或目录
[root@localhost ~]# ls xx || date
ls: 无法访问xx: 没有那个文件或目录
20210615日 星期二 10:57:29 CST
[root@localhost ~]# 


[root@localhost ~]# [ 8 -gt 2 -a 8 -gt 5 ] && echo y || echo n
y
[root@localhost ~]# [ 8 -gt 2 -a 8 -lt 5 ] && echo y || echo n
n
[root@localhost ~]# [ 8 -gt 2 -o 8 -lt 5 ] && echo y || echo n
y


[root@localhost ~]# [[ 8 -gt 2  &&  8 -lt 5 ]]  && echo y || echo n
n
[root@localhost ~]# [[ 8 -gt 2  ||  8 -lt 5 ]]  && echo y || echo n
y
[root@localhost ~]# 


[root@localhost ~]# [[ abc == abc* ]] && echo y || echo n
y
[root@localhost ~]# [ abc == abc* ] && echo y || echo n
n
[root@localhost ~]# [ abc* == abc* ] && echo y || echo n
y
[root@localhost ~]# 


2.if语句

(1)单分支结构

在这里插入图片描述
判断一个文件是不是脚本
在这里插入图片描述

(2)双分支结构

在这里插入图片描述
判断ip是否在线
在这里插入图片描述

(3)多分支结构

在这里插入图片描述

写一个判定成绩的脚本
在这里插入图片描述

判断一个用户是否有家目录(默认在/home下),有打印正常,没有询问是否删除,是就删除

在这里插入图片描述

四.shell脚本之case语句

1.case语句的结构

case语句主要适用于以下情况:某个变量存在多种取值,需要对其中的每一种取值分别执行不同的命令序列。

case 变量值 in
模式一)
命令序列1
;;
模式二)
命令序列2
;;

*)
默认命令序列
esac

2.case语句应用示例

vim fan.sh
在这里插入图片描述

[root@localhost ~]# bash fan.sh
请输入星期几:星期一
吃牛排
[root@localhost ~]# bash fan.sh
请输入星期几:周日
吃鲍鱼
[root@localhost ~]# 
[root@localhost ~]# bash fan.sh
请输入星期几:八
输入错误
[root@localhost ~]# 


五.shell脚本之循环语句

1.for循环语句

读取不通的变量值,用来逐个执行同一组命令
在这里插入图片描述
打印5遍hello的几种for循环方式
在这里插入图片描述
也可以引入位置参数

vim 6.sh
在这里插入图片描述

[root@localhost ~]# bash 6.sh hello world nihao wangwu lisi
hello
world
nihao
wangwu
lisi
[root@localhost ~]# 

vim 7.sh
在这里插入图片描述

[root@localhost ~]# bash 7.sh hello world nihao wangwu lisi
hello
hello
hello
hello
hello
[root@localhost ~]# 

2.while循环语句

重复测试某个条件,只要成立则反复执行
在这里插入图片描述

在这里插入图片描述

打印1到5
vim 8.sh
在这里插入图片描述

[root@localhost ~]# bash 8.sh
1
2
3
4
5
[root@localhost ~]# 

3.until循环语句

重复测试某个条件,只要条件不成立则反复执行

在这里插入图片描述
计算从1加到100的和

vim qiuhe.sh

在这里插入图片描述

[root@localhost ~]# bash qiuhe.sh
5050

说明:
死循环
while true
until false

六.shell函数

将命令按格式卸载一起,以便可以重复的使用

shell函数的定义
基本格式
function 函数名(){

命令序列

return x
}

调用函数的方法
函数名 参数1 参数2

函数返回状态码
函数的最后一条命令的执行结果为返回码

return 指定返回码的值 范围是0-255

计算阶乘运用调用函数
在这里插入图片描述

七.shell数组

应用场景包括

获取数组长度
获取元素长度
遍历元素
元素切片
元素替换
元素删除

数组
a(1 2 3 4 5 )
数组内每一位对应一个下标
每一位的对应关系如下
a[0]=1,a[1]=2,a[2]=3,a[3]=4,a[4]=5

[root@localhost ~]# a=(1 2 3 4 5)
[root@localhost ~]# echo ${a[1]}
2
[root@localhost ~]# echo ${a[*]}
1 2 3 4 5
[root@localhost ~]# echo ${a[@]}
1 2 3 4 5
[root@localhost ~]# echo ${#a[@]}
5
[root@localhost ~]#
[root@localhost ~]# fruit=([0]=apple [1]=orange [2]=banana)
[root@localhost ~]# echo ${fruit[*]}
apple orange banana
[root@localhost ~]# fruit[4]=tomato
[root@localhost ~]# echo ${fruit[*]}
apple orange banana tomato
[root@localhost ~]#
[root@localhost ~]# aa=( 1 2 lisi tomato)
[root@localhost ~]# echo ${aa[*]}
1 2 lisi tomato

list 列表

也可以把文件内容输出到列表
list= `cat 11.txt `

[root@localhost ~]# echo "1 2 3 4 5 6 7 8 " > 11.txt
[root@localhost ~]# cat 11.txt
1 2 3 4 5 6 7 8
[root@localhost ~]# list=`cat 11.txt`
[root@localhost ~]# echo ${list[*]}
1 2 3 4 5 6 7 8

[root@localhost ~]# list=`cat /etc/passwd`
[root@localhost ~]# list1=($list)
[root@localhost ~]# echo ${#list1[*]}      //参数个数
103


元素切片

[root@localhost ~]# a=(1 2 3 4 5 6)
[root@localhost ~]# echo ${a[*]:1:3}   //切1个,打印3个
2 3 4
[root@localhost ~]# echo ${a[*]:2:3}   //切2个,打印3个
3 4 5

元素替换

[root@localhost ~]# a=(1 2 3 4 5 6)
[root@localhost ~]# echo ${a[*]}
1 2 3 4 5 6
[root@localhost ~]# echo ${a[*]/6/16}      //是临时的
1 2 3 4 5 16
[root@localhost ~]# echo ${a[*]}
1 2 3 4 5 6
[root@localhost ~]# a[5]=16
[root@localhost ~]# echo ${a[*]}
1 2 3 4 5 16
[root@localhost ~]#

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值