1.shell介绍
Shell既是命令语言又是程序设计语言。Shell脚本是为shell编写的脚本程序。所需要的环境只要是一个文本编辑器和一个脚本解释器就行。
在Linux中shell类型有很多,大多数Linux系统默认的shell就是bash。
Linux中的shell脚本本质上是命令的集合。通过Shell脚本,用户可以自动化许多常见的系统管理任务,从而节省时间并提高工作效率。
2.第一个shell脚本
创建一个test1.sh文件,并对其添加内容,.sh后缀是为了区分该文件是shell脚本,sh +文件名可以直接运行该脚本。
[root@server shell]# vim test1.sh
[root@server shell]# cat test1.sh
#!/bin/bash
echo "This is first shell!"
[root@server shell]# sh test1.sh
This is first shell!
#!/bin/bash代表着该文件使用的是bash语法,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。
echo代表着直接输出双引号内的内容,用法是echo “”。
3.变量
变量是用来存储数据值的名称。
创建一个test2.sh文件,并定义变量
[root@server shell]# vim test2.sh
[root@server shell]# cat test2.sh
#!/bin/bash
a="This is second test"
echo "$a"
[root@server shell]# sh test2.sh
This is second test
可以看到这里定义变量a=”This is second test”,用echo命令直接输出$a,这里的$符号表示调用变量,输出的结果就是a的内容。
变量名的命名须遵循如下规则:
只包含字母、数字和下划线
不能以数字开头
避免使用 Shell 关键字
使用大写字母表示常量: 习惯上,常量的变量名通常使用大写字母
避免使用空格
4.传递参数
在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为 $n,n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数。
可以使用 $1、$2 等来引用传递给脚本的参数,其中 $1 表示第一个参数,$2 表示第二个参数,依此类推。
[root@server shell]# vim test3.sh
[root@server shell]# sh test3.sh
执行的文件名:test3.sh
第一个参数为:
第二个参数为:
第三个参数为:
[root@server shell]# sh test3.sh a b c
执行的文件名:test3.sh
第一个参数为:a
第二个参数为:b
第三个参数为:c
[root@server shell]# cat test3.sh
#!/bin/bash
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
可以看到第一次执行脚本的时候,脚本内容没有任何变化的输出了,在第二次执行脚本时,加入了a b c三个参数,脚本输入的内容就依次变成了a b c,其中$0表示执行的脚本的名称。
另外,还有其他的特殊字符
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数。 如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID |
$@ | 与$*相同,都是使用时加引号,并在引号中返回每个参数。 如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。 |
$- | 显示Shell使用的当前选项,与set命令功能相同。 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误 |
5.数学运算
原生的bash不支持简单的运算,但是可以用一些工具进行,如expr,也是较为常用的一种方式。
[root@server shell]# vim test4.sh
[root@server shell]# cat test4.sh
#!/bin/bash
a=10
b=20
c=`expr $a + $b`
echo "两数相加:$c"
[root@server shell]# sh test4.sh
两数相加:30
如图所示,通过expr工具,成功的计算出算式的结果。
也有其他的方式计算结果
[root@server shell]# cat sum.sh
#!/bin/bash
a=6
b=2
sum=$[$a+$b]
echo "$a+$b=$sum"
[root@server shell]# sh sum.sh
6+2=8
这种方式同样也可以计算出结果。
6.if判断
基本结构:
If 判断语句; then
fi
示例一
[root@server shell]# vim if1.sh
[root@server shell]# cat if1.sh
#!bin/bash
a=2
if [ $a -gt 4 ]
then
echo ok
fi
该脚本想表达的是如果a大于4那么就输出ok,可以看到此处a=2,所以输出时没有任何结果,将a的值改为6再次运行脚本
可以看到输入的结果是ok
Ps:shell中的比较运算符:
-eq //等于
-ne //不等于
-gt //大于 (greater)
-lt //小于 (less)
-ge //大于等于
-le //小于等于
示例二
#!bin/bash
a=6
if [ $a -gt 10 ]
then
echo ok
else
echo "not ok"
fi
此处用到了if...else语句,意思是如果a>10,那么就输出ok,否则就输出not ok,可以看到这里a=6,所以输出not ok
示例三
#!/bin/bash
a=9
if [ $a -gt 10 ]
then
echo ok
elif [ $a -eq 10 ]
then
echo "very ok"
else [ $a -lt 10 ]
echo "not ok"
fi
此处用到了if...elif...else语句,意思是如果a>10则输出ok,a=10则输出 very ok,a<10则输出not ok,此处a=9,所以输出not ok
示例四
#!/bin/bash
a=66
if [ $a -gt 18 ]
then
if [ $a -lt 60 ]
then
echo "成年人"
else
echo "老年人"
fi
else
echo "未成年"
fi
此处用到了嵌套,意思是如果a>18,那么就有两种可能,一种是大于18,小于60,那么就会输出成年人,否则就会输出老年人,如果a<18,那么直接输出未成年,此处a=66,所以直接输出老年人
ps:
在 `if` 语句中,可以使用以下条件测试:
- `[ -z string ]`:字符串为空
- `[ -n string ]`:字符串不为空
- `[ string1 = string2 ]`:字符串相等
- `[ string1 != string2 ]`:字符串不相等
- `[ -e file ]`:文件存在
- `[ -f file ]`:文件存在且是普通文件
- `[ -d file ]`:文件存在且是目录
- `[ -x file ]`:文件存在且可执行
7.case判断
示例:
#/bin/bash
read -p "请输入数字:" n
if [ -z"$n" ]
then
echo "请输入数字"
else
exit 1
fi
if [ -n "$n1" ]
then
echo "请输入数字"
exit 1
fi
if [ $n -lt 60 ]&&[ $n -ge 0 ]
then
tag=1
elif [ $n -ge 60 ]&&[ $n -lt 80 ]
then
tag=2
elif [ $n -ge 80 ]&&[ $n -lt 90 ]
then
tag=3
elif [ $n -ge 90 ]&&[ $n -le 100 ]
then
tag=4
else
tag=0
fi
case $tag in
1)
echo "不及格"
;;
2)
echo "及格"
;;
3)
echo "良好"
;;
4)
echo "优秀"
;;
*)
echo "范围在0-100"
;;
esac
此处用到的是case判断,意思是在1-100内输入一个数字,0-60代表不及,61-80代表及格,81-90代表良好,91-100是优秀。
8.for循环
示例:
#!/bin/bash
sum=0
for i in `seq 1 10`
do
sum=$[$sum+$i]
echo $i
done
echo $sum
此处用的是for循环语句,意思是循环十次后输出sum的结果。
9.while循环
示例一
#!/bin/bash
sum=0
i=2
while [ $i -le 100 ]
do
let sum=$sum+$i
let i+=2
done
echo "1-100的偶数和为:$sum"
此处用到的是while循环语句,意思是求1-100的偶数和。
示例二
#!/bin/bash
while :
do
read -p "请输入一个数字:" n
if [ -z "$n" ]
then
echo "你需要输入一些东西"
continue
fi
n1=`echo $n|sed 's/[0-9]//g '`
if [ -n "$n1" ]
then
echo "你只需要输入数字"
continue
fi
break
done
echo $n
此处也是用的while循环,意思是运行脚本时会让你输入东西,若是什么都不输入的话就会提示“你需要输入一些东西”,若是输入的不是数字的话及聚会提示“你只需要输入数字”,当输入数字时就会直接将数字输出。
10.数组
定义一个数组,数组中可以存放多个值,bash shell只支持一维数组
示例一
#!/bin/bash
a=(1,2,3,4,5,6)
echo ${a[@]}
可以看到这里定义了一个数组a,此处将数组内的所有内容都输出了。
示例二
#!/bin/bash
a=(1 2 3 4 5 6)
echo ${#a[@]}
可以看到输出的是数组的元素个数,总共有6个
示例三
#!/bin/bash
a=(1 2 3 4 5 6)
echo ${a[3]}
这里输出了第四个元素,数组元素的计数是从0开始算,所以这里输出4
11.函数
示例一
#!/bin/bash
fun (){
echo "This is my first shell fun"
}
echo "函数执行中"
fun
echo "函数执行完毕"
示例二
函数运算
#/bin/bash
sum(){
echo "该函数会对输入的数字进行相加"
echo "请输入第一个数字:"
read a
echo "请输入第二个数字"
read b
echo "两个数字分别为$a和$b"
return $(($a+$b))
}
sum
echo "两数相加的和为$?"
这里用到了return语句,表示返回,函数返回值通过$?获取,要注意的是return 语句只能返回一个介于 0 到 255 之间的整数
示例三
含参函数
#!/bin/bash
a(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
a 1 2 3 4 5 6 7 8 9 34 73
注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。
12.重定向
在 Shell 编程中,输入/输出重定向是一种强大的工具,用于控制命令如何处理输入和输出数据流。
输出重定向:输出重定向允许将命令的标准输出发送到文件
示例一
此处可以看到ls-l 命令的内容被重定向到了1.txt文件里面
追加重定向:有时候需要将输出追加到文件末尾而不是覆盖原有内容
示例二
可以看到find /etc/*.conf命令的输出被追加到了1.txt文件,没有将原有内容覆盖,在原有内容后面输出
输入重定向:输入重定向允许从文件而不是键盘读取输入
示例三
可以看到输入重定向之后,1.txt的文件内容被改变了顺序,sort命令具有排序的功能
重定向标准错误:有时候需要将错误消息重定向到文件
示例四
可以看到这里用grep查询一个不存在的文件,内容重定向到了error.log中,查看该文件,可以看到报错日志
并标准输出和标准错误:有时候希望将标准输出和标准错误合并到同一个文件中
示例五
这里可以看到将正确和错误的输出都放到了111.log文件中,第一次输出的命令是正确的所以正常输出,第二次查找了一个不存在的目录,所以输出错误提示
13.sed常用用法
Sed是一种流编程器,是文本处理中常用的工具。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作。
示例一
替换操作
sed -n 's/111/444/p' 1.txt
表示只打印替换的部分
sed -i 's/111/444/g' 1.txt
此处用到了-i,表示直接编辑文件,s表示指定字符,g表示匹配全局变量。整体作用是将文件内的所有第一行的111替换成444
示例二
删除操作
删除空白行
sed '/^$/d' 1.txt
可以看到1.txt文件中有空白行,输入命令后再次查看空白行已经消失。^表示匹配行的开始,如^111表示匹配以111开头的行。$表示匹配行的结束,如$111表示匹配以111结束的行。
删除文件的第二行
sed '2d' 1.txt
示例三
多点编辑
-e选项允许在同一行里执行多条命令
sed -e '1,5d' -e 's/000/111/' 2.txt
这条命令的意思是删除文件内的1-5行,并将文件内的000替换为111。
14.grep基础用法
grep是一个强大的文本搜索工具,可以用于在文件中查找特定的文本模式或正则表达式。grep具有多种选项,可以根据需要自定义搜索行为。grep命令可以与其他命令结合使用,例如awk、sed等命令,以便对结果进行进一步的处理。
示例 一
在单个文件下查找内容
grep 111 1.txt
意思是在1.txt文件中查找111,若是查找到了便输出,查找不到则不输出。
示例二
在多个文件下查找内容
grep 111 1.txt 2.txt 3.txt
意思是在1.txt 2.txt 3.txt文件中查找111
示例三
grep "^[1-9]" 1.txt
意思是在1.txt文件中查询行首是1-9的内容
示例四
grep -c "111" 1.txt
意思是统计1.txt文件中111的行数
示例五
grep -o "111" 1.txt
意思是在结果中显示匹配的文本