Shell基础
Shell含义
Linux内核用于驱动硬件;而用户使用应用程序想要与硬件交互则需要Shell程序
Shell 是一个程序,提供一个与用户对话的环境。这个环境只有一个命令提示符,让用户从键盘输入命令,所以又称为命令行环境(command line interface,简写为 CLI;图形界面(GUI))。Shell 接收到用户输入的命令,将命令送入操作系统执行,并将结果返回给用户。
👣bash是Shell的一种..
bash大多数 Linux 系统默认使用的 shell.
Shell种类
- Bourne Shell
- Bourne Again shell(bash)
- C Shell(csh)
- TENEX C Shell(tcsh)
- Korn shell(ksh)
- Z Shell(zsh)
- Friendly Interactive Shell(fish)
事先注意事项
- 函数定义必须在执行语句之前,也就是#!bin/bash下面,否则后面执行函数调用将无法被调用,会提示command not found
- 创建变量名称时不能以数字开头
- 创建变量赋值;等号两侧不能有空格
- 变量默认类型都是字符串类型,无法直接进行数值运算
- 变量值有空格,需要使用双引号或单引号括起来
Debug模式
1
2
3
4
5
6
7
#全局开启Debug
set -x #开启Debug模式;输入每个命令都会显示执行过程;切勿在命令行开启
set +x #关闭Debug模式
#只针对脚本开启Debug
bash -x #只显示脚本的执行过程
#带+号表示执行过程
#没带加号表示标准输出
命令提示符
进入命令行环境以后,用户会看到 Shell 的提示符。提示符往往是一串前缀,最后以一个美元符号$
结尾,用户可以在这个符号后面输入各种命令
1
[user@hostname] $
上面例子中,完整的提示符是[user@hostname] $
,其中前缀是用户名(user
)加上@
,再加主机名(hostname
)。比如,用户名是bill
,主机名是home-machine
,前缀就是bill@home-machine
。
注意,根用户(root)的提示符,不以美元符号($
)结尾,而以井号(#
)结尾,用来提醒用户,现在具有根权限,可以执行各种操作,务必小心,不要出现误操作。
查看当前设备默认的Shell
1
root@R-PC:/# echo $SHELL
查看当前Linux系统安装的所有Shell
1
root@R-PC:/# cat /etc/shells
Shell脚本格式
基本格式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash #定义一个解释器
变量名 = "$(Shell命令)"
echo $变量名 #使用一个定义过的变量,只要在变量名前面加美元符号即可
echo "$(touch 文件名(PAth))" #创建文件
echo $变量名 >> 文件名 #将输出的指令内容写入到这个文件
#函数用法
函数名(){
语句
}
函数名 #调用函数
#read用法(接收用户输入)
read [自定义变量名]
echo $[自定义变量名]
#将用户的输入自动保存到这个变量中,可以用echo $变量名输出显示
局部变量
撤销变量-unset-
1
2
3
4
5
root@wyw-PC:~# a=1
root@wyw-PC:~# echo $a
1
root@wyw-PC:~# unset a
root@wyw-PC:~# echo $a
声明静态变量-readonly-
注意:不能撤销(unset)
1
2
3
4
5
root@wyw-PC:~# readonly a=1
root@wyw-PC:~# echo $a
1
root@wyw-PC:~# unset a
bash: unset: a:无法取消设定: 只读 variable
全局变量
将局部变量提升为全局变量-export-
1
2
root@wyw-PC:/bin# export A=2
#意味着到哪个路径或哪个.sh文件里面都可以使用这个变量
特殊变量
$n
功能描述:
-
传递给脚本或函数的参数
-
n为数字,$0获取当前脚本文件名称
-
$1~$9代表输入的第1到第9个参数
-
10以上的参数需要用大括号包含,如${10}
$#
功能描述:
- 获取所有输入参数的个数(判断你输入的有几个参数,用于循环)
$*
功能描述:
-
所有输入的参数
-
$*把所有参数看成一个整体(整体输出)
$@
功能描述:
-
所有输入的参数
-
$@把每个参数区别对待(逐个输出)
$?
功能描述:
在Linux系统中,每当一条命令执行完成后,系统都会返回一个退出状态,这个状态被存放在$? 这个变量中,是一个整数值,我们可以根据这个值来判断命令运行的结果是否正确。
通常情况下,退出状态值为0,表示执行成功,不为0的时候表示执行失败。
1
2
3
4
5
6
7
8
9
0 (运行成功)
1-255 (运行失败,脚本命令、系统命令错误或参数传递错误)
126 (找到了该命令但无法执行)
127 (未找到要运行的命令)
128 (命令被系统强行结束)
Read用法(用户提示输入)
1
2
3
#!/bin/bash
read -t 3 -p "3秒内输入参数赋值给变量" A #将用户的输入赋值给变量A
echo $A
参数
- -t 用户输入的等待时间
- -p 脚本执行时对用户输入的提示信息
提示
- 不跟时间参数会一直等待用户输入
- 用户输入的值最后会赋值给创建的变量
运算符
加减乘除取余运算(+ , - , \ * , / , %)-expr-、乘号(\ *)
注意:expr运算符之间要有空格
1
2
root@wyw-PC:/# expr `expr 2 + 2` \* 2 # ` `表示优先执行
8
采用$[运算式]方式、乘号(*)
1
2
3
root@wyw-PC:/# A=$[(2+3)*4] #这里的乘号与expr方式有所区别
root@wyw-PC:/# echo $A
20
[ 条件 ]
- [ ]用于存放判断条件
-
条件前后要有空格
- 利用echo $?输出结果;结果为0即为真,为0及为假
1
2
3
4
5
6
root@wyw-PC:/# [ 23 -lt 22 ]
root@wyw-PC:/# echo $?
1
root@wyw-PC:/# [ 23 -gt 22 ]
root@wyw-PC:/# echo $?
0
test 条件
1
2
3
4
5
# -v 变量名,用于判断变量是否定义;结果为0即定义
# -e 文件名,用于判断文件是否存在
[root@VM-0-5-centos ~]# test -e if.sh
[root@VM-0-5-centos ~]# echo $?
0
整数比较运算符
两个整数之间比较
1
2
3
4
5
6
7
= 字符串比较
-eq 等于(equal) -ne 不等于(Not equal)
-lt 小于(less than) -le 小于等于(less equal)
-gt 大于(greater than) -ge 大于等于(greater equal)
字符串相关运算符
1
2
3
4
-n string # 字符串不为空则为真
-z string # 字符串为空则为真
string1 = string2 # 字符串相等则为真 (或者 == 也可以)
string1 != string2 # 字符串不等则为真
这里有一个需要注意的地方,就是使用 -n 这个运算符进行判断的时候需要注意在变量两边加上双引号。
例如 if [ -n $string ] 应该写成 if [ -n “$string” ] ,不然该表达式总是会返回真,因为当string变量为空的时候就相当于是 if [ -n ]。
文件权限操作符
1
2
3
4
5
-r 读权限(read)
-w 写权限(write)
-x 执行权限(execute)
1
2
3
root@wyw-PC:/# [ -x xunjian.sh ]
root@wyw-PC:/# echo $?
1
文件类型操作符
1
2
3
4
5
6
7
8
9
-d file # 测试file是否为目录
-e file # 测试file是否存在
-f file # 测试file是否为普通文件
-r file # 测试file是否是进程可读文件
-s file # 测试file的长度是否不为0
-w file # 测试file是否是进程可写文件
-x file # 测试file是否是进程可执行文件
-l file # 测试file是否符号化链接
-c file #判断是不是一个字符设备文件
1
2
3
root@wyw-PC:/# [ -d 123 ] #123为文件名称
root@wyw-PC:/# echo $?
0
|逻辑运算符
1
2
3
! # 非
-a # 与(或者&&)
-o # 或(或者||)
1
2
3
4
5
6
7
8
9
if [ $value == "stop" -o $value == "restart" ]; then
excute=$value
fi
或者
if [ $value == "stop" ] || [ $value == "restart" ]; then
excute=$value
fi
if判断
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash
if [ 条件 ];then 或者 if [ 条件 ] 换行then
程序
elif [ 条件 ];then
程序
fi #结束
#第三种嵌套写法
if [];then
程序
else
if [];then
程序
else
程序
fi
fi
case语句
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
case $变量名 in
变量值1)
程序输出...
;; #匹配上双分号结束
变量值1)
程序输出...
;; #匹配上双分号结束
..........
*) #相当于默认值default;其他都不匹配就匹配默认值
程序输出...
;; #匹配上双分号结束
esac #结束
for循环
写法一
1
2
3
4
5
#!/bin/bash
for ((①初始值;②循环控制条件;④变量变化)) #执行流程①②③④
do
③程序
done #do和done对应大括号{}
写法二(类似与Python中的遍历循环)
1
2
3
4
5
#!/bin/bash
for 变量名 in 变量值1 变量值2 变量值3 #将变量值依次赋值给变量,类似与Python中的遍历
do
程序
done
while循环
1
2
3
4
5
while [ ①条件判断 ]
do
程序②
程序③
done
函数
系统函数’
basename删除前面文件路径,截取文件名称
格式
1
2
3
4
5
6
7
basename [文件路径/前缀字符] [要被截取的后缀]
[root@VM-4-7-centos /]# basename 123.sh .sh #截取文件名称
123
[root@VM-4-7-centos /]# basename bin in
b
[root@VM-4-7-centos /]# basename 123 23 #截取字符
1
dirname删除后面文件名称,截取文件路径
格式
1
2
[root@VM-4-7-centos /]# dirname data/v2ray.crt
data
自定义函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#必须先声明函数,不然无法调用
function(可写可不写) 函数名称()
{
程序内容
}
函数名称调用()
#示例
#!/bin/bash
function sum()
{
s=0
s=$[$1+$2]
echo $s
}
read -p "输入域名:" DNS
read -p "输入IP地址:" IP
sum $DNS $IP
Shell工具
截取列工具- cut -
作用:在一大堆数据当中剪出核心关键的
选项参数
-f 取出第几列或者第几列到第几列(1-7…….)
-d 指定分隔符(分割列);以什么符号分割列
-c 从第几个字符开始取值;可以是以逗号分隔的数字的列表,也可以是以连字符分隔的数字的范围
-b 提取指定的字节,也可以指定一个范围
文本过滤工具- grep -
文本编辑工具- sed -
替换、添加、删除
格式
sed 参数 ‘ 执行动作 ‘ 文件名
^表示首行或者是^root以root开头的那一行 $表示尾行
[参数]:
- -i 对源文件进行修改
- -e 不会修改源文件
- -n 显示行数
'’动作’‘:
- a 添加;当前的下一行
- i 插入;当前的上一行
- d 删除
- s 替换
- p 打印第几行;结合-n使用;例如 sed -n “4p” 就是输出打印第四行内容
例:
1
2
3
4
5
6
7
8
9
10
11
12
13
# N表示第几行
# 'N,Ns/d/a...' 指定范围
#添加a
sed 'Na 文本内容' 文件名 #在指定当前行数的下一行添加内容
#删除d
sed '/要被删除的文本/d' 文件名 #删除匹配上文本的行
sed 'Nd' 文件名 #删除某一行
#替换s
sed 's/要被取代的文本/新的文本/g' 文件名 #匹配文件中所有要被替换的文本;加g是全局替换,不加默认匹配替换第一个
sed 'Ns/要被取代的文本/新的文本 /' 文件名 #指定某一行匹配要被替换的文本
sed 'N,Ns' #替换指定行数范围之间所匹配的文本
统计、分析日志、过滤 - awk -
擅长数据切片,数据格式化,功能最复杂
正则表达式
^ | 如:”awk^”,匹配以awk单词开头的行 |
---|---|
$ | 如:”awk$”,匹配以awk单词结尾的行 |
^$ | 表示空行(头尾什么都没有) |
. | 匹配任意一个字符且只有一个字符,不能匹配空行 |
\ | 转义字符,使\后面的字符按愿意输出,还原本意,如:”\ .” 代表小数点 |
* | |
.* | 匹配所有内容 |
^.* | 匹配以任意多个字符开头的内容 |
.*$ | 匹配以任意多个字符结尾的内容 |
[a b c] | 匹配集合内任意一个字符,a或者b或者c,也可以写成[a-c] |
^[a b c] | 匹配以集合内任意一个字符开头的内容 |
[^a b c] | 匹配不以集合内任意一个字符开头的内容 |
输出彩色字体
至少需要两部分, \033[31m 和\033[0m
\033[31m理解成”开始输出红色字符” ,把\033[0m理解成”结束输出红色字符”
1
2
3
4
#输出红色字体
echo -e "\033[1;32m文本\033[0m"
#分号前代表背景色
#分号后代表字体颜色
定义变量值为一个命令
1
2
3
root@wyw-PC:/# B="$(ls)" #调用定义过的变量,要变量名前面加$符号即可
root@wyw-PC:/# echo $B
123.sh bin boot data dev etc home lib lib32 lib64 libx32 lost+found media proc recovery root run sbin server.sh srv sys tmp usr var wyw xunjian.sh
1
2
3
A=1 #给变量赋值(初始化)
A #变量
$A #调用变量(变量值)
Shell脚本保存格式:文件名.sh
执行格式:./文件名.sh(一般没有执行权限) 或者 shell种类(bash、sh等) 文件名.sh