一、Shell脚本入门
Shell
脚本与Windows/Dos
下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。Shell
本身是一个用C
语言编写的程序,它是用户使用Linux
的桥梁。
1.1 简单脚本
脚本都是以如下格式开头
#!/bin/bash
创建一个简单的脚本
# 创建脚本文件
vi HelloWord.sh
# 添加如下内容
#!/bin/bash
echo "helloword"
# 运行脚本
bash HelloWord.sh
1.2 多命令处理脚本
例如我们需要创建一个脚本,来帮助我们在家目录下创建一个名为test.txt
的文件,并且在里面添加 “多命令处理脚本文件” 字样
#!/bin/bash
cd ~
touch test.txt
echo "多命令处理脚本文件" >>test.txt
二、 Shell中的变量
2.1 系统变量
可以方便获取系统的变量
$HOME
$PWD
$SHELL
$USER
可以配合输出或者自定义变量使用
echo $USER
2.2 自定义变量
- 用来记录我们自己的变量,可以由数字、字母、下划线组成,不可以用数字开头
- 变量类型默认是字符串类型,无法直接进行数据运算
- 使用
=
来赋值,且等号的左右两边不可以出现空格 - 如果赋值中有空格,则需要将整个值用
“”
包括
# 自定义变量
age=23
address="Jiang Xi"
echo $age
# 取消自定义的变量
unset age
如果需要设置静态变量(即不可以被unset
的变量,如需取消,则需要重启虚拟机)
readonly age=34
2.3 特殊变量
2.3.1 $n
n
为数字,0
代表脚本名称,10
以内参数用1-9
表 示 ,10
以上的需要用大括号包含,例如{10}
,每个数字顺序表示我们输入的参数
例如我们创建一个脚本文件
#!/bin/bash
echo 正在执行脚本名称是$0
echo 第一个参数age=$1
echo 第二个参数是address="$2"
echo 全部的参数是 $1 $2
运行该脚本文件,则结果如下,即$0
获取的是脚本名称test.sh
,$1
获取的是第一个参数,也就是31
,第二个参数类似,同时证明参数获取无视双引号
bash test.sh 32 JiangXi
2.3.2 $#
可以获取输入的参数个数,常用于循环统计
echo $#
2.3.3 $*和$@
$*
(描述:代表命令行中所有的参数,把所有参数看成一个整体)$@
(描述:也代表命令行中所有的参数,不过把每个参数区分对待)
echo $*
echo $@
2.3.4 $?
用于判断上一条命令的返回状态
- 若返回
0
,则上一条命令执行正确 - 若返回非
0
,则上一条命令执行不正确
echo $?
三、运算符
- 运算规则:
expr
或$[]
- 符号为
+ - \* / %
,特别要注意,乘号需要利用转义符号表示\*
- 运算符和数字之间要有空格
- 如果需要实现
()
的操作,则需要使用==`==符号
# 实现 3+2
expr 3 + 2
# 实现 3+4*2
expr 3 + `expr 4 \* 2`
# 实现 3+4*2
echo $[3+(4*2)]
四、条件判断
- 判断规则:
[ condition ]
- 注意:
condition
前后要存在空格
4.1 整数之间的比较
-lt
:小于-le
:小于等于-eq
:等于-gt
:大于-ge
:大于等于-ne
:不等于
# 条件判断
[ 23 -gt 45 ]
# 查看是否生效
echo $?
4.2 文件权限判断
-r
:读权限-w
:写权限-x
:执行权限
# 判断文件是否为可写文件
[ -w test.sh ]
# 查看是否生效
echo $?
4.3 文件类型判断
-f
:文件存在并且是一个常规文件-e
:文件存在-d
:文件存在并且是一个目录
# 查看是否为文件
[ -f test.sh]
# 查看是否生效
echo $?
4.4 多条件判断
利用&&
或者||
来进行判断
# 判断文件是否存在
[ -e text.sh ] && echo “test.sh文件存在” || echo “test.sh文件不存在”
五、流程控制
5.1 if
格式如下:
#!/bin/bash
if [ 条件判断 ]
then
程序
elif [ 条件判断 ]
then
程序
fi
示例如下:
# 输入参数,如果是60以下,则输出"考试不合格",否则输出"考试通过"
#!/bin/bash
if [ $1 -le 60 ]
then
echo "考试不合格"
elif [ $1 -gt 60 ]
then
echo "考试通过"
fi
5.2 case
规则如下:
- 其中
*
表示默认匹配值
#!/bin/bash
case 参数 in
参数匹配值)
程序
;;
另一个参数匹配值)
程序
;;
*)
程序
;;
esac
示例如下:
# 输入参数,如果参数为0-59,则输出"不及格",如果参数为60-89,则输出"良好",如果参数为90-100,则输出"优秀",否则输出"成绩不存在"
#!/bin/bash
case $1 in
[1-5][0-9]|[0-9] )
echo "不及格"
;;
[6-8][0-9] )
echo "良好"
;;
[9][0-9]|100 )
echo "优秀"
;;
*)
echo "成绩不存在"
;;
esac
5.3 for
5.3.1 规则一
语法规则如下:
for((初始值;循环控制条件;变量变化))
do
程序
done
示例如下 :
- 其中
s=$[$s+$i]
表示赋值,$s
和$i
分别表示取值,$[$s+$i]
表示取里面两个数字累加的值,再赋值给s
# 累加1到100
#!/bin/bash
s=0
for((i=1;i<=100;i++))
do
s=$[$s+$i]
done
echo "1到100的累加值是 "$s
5.3.2 规则二
语法规则如下,为轮流赋值:
for 变量 in 值1 值2 值3……
do
程序
done
示例如下 :
# 测试轮流输出名字
#!/bin/bash
for name in $*
do
echo "my friend is $name"
done
5.4 while
规则如下:
while [ 条件判断 ]
do
程序
done
示例如下:
# 从1累加到100
#!/bin/bash
s=0
i=1
while [ $i -le 100 ]
do
s=$[$s+$i]
i=$[$i+1]
done
echo $s
六、read读取控制台的输入
帮助我们从控制台读取键盘输入的参数,基础规则如下:
read(选项)(参数)
选项:
-p
:指定读取时的提示符-t
:指定读取时等待的时间(秒)
参数:
- 变量:指定读取值的值赋值给谁
# 获取键盘输入的名字
#!/bin/bash
read -t 7 -p "please enter your name: " NAME
echo $NAME
七、常用系统函数
7.1 basename
basename
命令会删掉所有的前缀包括最后一个‘/’
字符,然后将字符串显示出来
basename [string / pathname] [suffix]
[string / pathname]
:字符串或文件路径[suffix]
:去掉最后字符串的文件后缀
# 第一组测试
basename /home/yzx/read.sh
# 输出
read.sh
# 第二组测试
basename /home/yzx/read.sh .sh
# 输出
read
7.2 dirname
从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)
dirname [pathname]
示例如下
# 输入测试
dirname /home/yzx/read.sh
# 输出
/home/yzx
八、自定义函数
shell
是从上往下执行顺序,所以上面的函数并不知道下面函数的存在- 函数的返回值,只能通过
$?
来获得 - 自定义函数规则如下
[ function ] funname[()]
{
Action:
[return int;]
}
示例如下:
# 实现两个函数求和
#!/bin/bash
function sum()
{
s=0
s=$[$1+$2]
echo ”$1和$2的和是$s“
}
read -p "input your paratemer1:" p1
read -p "input your paratemer2:" p2
sum $p1 $p2
九、Shell工具
9.1 cut
cut
的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。cut
命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。
9.1.1 规则说明
特别说明:默认的分隔符是制表符
cut [参数选项] filename
9.1.2 参数说明
选线参数 | 功能 |
---|---|
-f | 列号,表示提取出第几列 |
-d | 分割符,按照指定的符号进行分割 |
9.1.3 实例操作
- 数据准备:创建一个文本文件
cut.txt
,存入以下内容
a complicated system of roads, lines, tubes, nerves, etc. that cross each other and are connected to each other
a number of computers and other devices that are connected together so that equipment and information can be shared
a group of radio or television stations in different places that are connected and that broadcast the same programmes at the same time
- 切割
cut.txt
第一列【空格切割,取出第一列】
cut -d " " -f 1 cut.txt
- 切割
cut.txt
第二、三列【空格切割,取出第二、三列】
cut -d " " -f 2,3 cut.txt
- 选取系统
PATH
变量值,第2
个“:”
开始后的所有路径(其中特别要注意,如果只写了-
,说明到结尾或者从开头)【先打印,用冒号切割,然后取出第二行之后的内容】
echo $PATH | cut -d ":" -f 2-
- 切割
ifconfig
后打印的IP
地址
ifconfig ens33 | grep -w "inet" | cut -d "n" -f 2 | cut -d " " -f 2
9.2 sed
sed
是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed
命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。
9.2.1 规则说明
sed [选项] [动作] filename
9.2.2 参数说明
选线参数 | 功能 |
---|---|
-e | 允许对输入的数据进行多个动作的执行,如果只有一个动作可以不加参数 |
-i | 修改结果直接修改读取数据的文件 |
动作参数 | 功能 |
---|---|
a | 表示新增,a 的前面接数字表示在第几行前增添,后面可以接字串,在下一行出现,添加多行时,除最后一行外,每行末尾需要用“\n” 代表换行,格式为:[num a Str\nStr\nStr] |
d | 删除指定的行,格式为[num d] 或者[num1,num2 d] |
c | 替换某一行,格式为[num c newStr] |
s | 查找并且替换,格式为[num s/oldStr/newStr/g] ,其中g 表示全局替换 |
9.2.3 实例操作
- 在第二行后插入一句话
sed -i "2a insert into 2 line" sed.txt
- 在第一行之后插入三句话
sed -i "1a First sentence\nSecond sentence\nThird sentence" sed.txt
- 删除第二行的数据
sed "2d" sed.txt
- 删除包含
v
的一行
sed "/v/d" sed.txt
- 替换整个文本中的
a
为hello
sed "s/a/hello/g" sed.txt
- 将文本中的第二行替换为别的话
sed "2c change sentence" sed.txt
9.3 sort
将文件进行排序,并将排序结果标准输出
9.3.1 规则说明
sed [选项] [参数] filename
9.3.2 参数说明
选线参数 | 功能 |
---|---|
-n | 依照数值的大小排序 |
-r | 以相反的顺序来排序 |
-t | 设置排序时所用的分隔字符 |
-k | 指定需要排序的列 |
9.3.3 实例操作
- 存在一个文本文件
sort.txt
bb:40:5.4
bd:20:4.2
xz:50:2.3
cls:10:3.5
ss:30:1.6
- 按照
“:”
分割后的第二列倒序排序。
sort -t ":" -nrk 2 sort.txt