七、Shell语言
(一)、shell概述
1、Shell简介
· Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell来启动、挂起、停止甚至是编写一些程序。
· Shell还是一个功能相当强大的编程语言,易编写,易调试,灵活性较强。Shell是解释执行的脚本语言,在Shell中可以直接调用Linux系统命令。
2、Shell脚本的执行方式
echo输出命令
[root@localhost ~]#echo [选项] [输出内容]
选项:
-e: 支持反斜线控制的字符转换
[root@localhost ~]#echo -e “ab/bc”
#删除左侧字符
[root@localhost ~]#echo -e “a\tb\tc\nd\te\tf”
#制表符与换行符
[root@localhost ~]#echo -e
“x61\t\x62\t\x63\n\x64\t\x65\t\x66”
#按照十六进制ASCII码也同样可以输出
脚本执行
>>touch test.sh #新建文件
>>vim test.sh #编辑文件指令
>键入 i
>输入#!/bin/bash #自成一行标明shell种类
echo hello world; #内容
键入: esc #表示准备退出
输入: : wq #表示保存
>>chmod +x ./test.sh #使脚本具有执行权限
>>./test.sh #执行脚本 或使用 sh 文件名.后缀
3、Bash的基本功能
历史命令
[root@localhost ~]#history [选项] [历史命令保存文件]
选项:
-c: 清空历史命令
-w: 把缓存中的历史命令写入历史命令保存文件~/.bash_history
· 使用上、下箭头调用以前的历史命令
· 使用“!n”重复执行第n条历史命令
· 使用“!!”重复执行上一条命令
· 使用“!字串”重复执行最后一条以该字串开头的命令
命令与文件补全
· 在Bash中,命令与文件补全是非常方便与常用的功能,我们只要在输入命令或文件时,按“Tab”键就会自动进行补全。
命令别名与常用快捷键
1、命令别名alias
[root@localhost ~]#alias 别名=‘原命令’
#设定命令别名
[root@localhost ~]#alias
#查询命令别名
让别名永久生效
[root@localhost ~]#vi /root/.bashrc
删除别名
[root@localhost ~]#unalias 别名
2、Bash常用快捷键
输入输出重定向
1、标准输入输出
设备 | 设备文件名 | 文件描述符 | 类型 |
键盘 | /dev/stdin | 0 | 标准输入 |
显示器 | /dev/sdtout | 1 | 标准输出 |
显示器 | /dev/sdterr | 2 | 标准错误输出 |
2、输出重定向
3、输入重定向
[root@localhost ~]# wc [选项] [文件名]
选项:
-c 统计字节数
-w 统计单词数
-l 统计行数
多命令顺序执行与管道符
1、多命令顺序执行
[root@localhost ~]#dd [选项]
选项:
if=输入文件 制定源文件或源设备
of=输出文件 制定目标文件或目标设备
bs=字节数 制定一次输入/输出多少字节,即把这些字节看做一个数据块
count=个数 制定输入/输出多少个数据块
eg:[root@localhost ~]#date;dd if=/dev/zero of=/root/testfile bs=1k count=100000;date
[root@localhost ~]#ls anaconda-ks.cfg && echo yes
[root@localhost ~]#ls /root/test || echo "no
[root@localhost ~]#命令 && echo yes || echo no
[root@localhost~]#ls;date;cd /user;pwd
2、管道符
命令格式:
[root@localhost ~]#命令1 | 命令2
#命令1的正确输出作为命令2的操作对象
[root@localhost ~]#ll -a /etc/ | more
[root@localhost ~]#netstat -an | grep “ESTABLISHEN”
通配符和其他特殊符号
1、通配符
[root@localhost ~]#grep [选项] “搜索内容” 文件名
选项:
-i: 忽略大写
-n: 输出行号
-v: 反向查找
–color=auto 搜索出的关键字用颜色显示
2、Bash中其他特殊符号
单引号与双引号
[root@localhost ~]#name=sc
[root@localhost ~]#echo “KaTeX parse error: Expected 'EOF', got '#' at position 25: …ot@localhost ~]#̲echo 'name’
[root@localhost ~]#echo “KaTeX parse error: Expected 'EOF', got '#' at position 27: …ot@localhost ~]#̲echo '(date)’
4、变量
1、环境变量是什么
· 用户自定义变量只在当前的shell中生效,而环境变量会在当前Shell和这个Shell的所有子Shell当中生效。如果把环境变量写入相应的配置文件,那么这个环境变量就会在所有的Shell中生效。
2、设置环境变量
export 变量名=变量值
#申明变量
env
#查询变量
unset 变量名
#删除变量
3、位置参数变量
位置参数变量 | 作用 |
$n | n为数字,$0代表命令本身,$1-{10} |
$* | 这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体 |
$@ | 这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待 |
$# | 这个变量代表命令中所有参数的个数 |
例子:
#!/bin/bash
num1=$1
num2=$2
sum=num1+$num2))#变量sum的和是num1加num2
echo $sum
#打印变量sum的值
例子:
#!/bin/bash
echo “A total of $# parameters”
#使用$#代表所有参数的个数
echo “The parameters is:$*”
#使用$*代表所有的参数
echo “The parameters is:$@”
#使用$@也代表所有参数
例子:¥*与$@的区别
#!/bin/bash
for i in “$*”
#$*中的所有参数看成是一个整体,所以这个for循环只会循环一次
do
echo “The parameters is:$i”
done
x=1
for y in “$@”
#@”中有几个参数,就会循环几次do
echo “The parametery”x=x+1))done
4、预定义变量
预定义变量 | 作用 |
$? | 最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了 |
$$ | 当前进程的进程号(PID) |
$! | 后台运行的最后一个进程的进程号(PID) |
接收键盘输入
[root@localhost ~]#read 【选项】【变量名】
选项:
-p “提示信息”:在等待read输入时,输出提示信息
-t 秒数: read命令会一直等待用户输入,使用此选项可以指定等待时间
-n 字符数: read命令只接受指定的字符数,就会执行
-s: 隐藏输入的数据,适用于机密信息的输入
5、Bash运算符
数值运算和运算符
1、declare声明变量类型
[root@localhost ~]decaler [+/-][选项] 变量名
选项:
-: 给变量设定类型属性
+: 取消变量的类型属性
-i: 将变量声明为整数型(integer)
-x: 将变量声明为环境变量
-p: 显示指定变量的被声明的类型
2、数值运算——方法1
[root@localhost ~]# aa=11
[root@localhost ~]# bb=22
#给变量aa和bb赋值
[root@localhost ~]#decaler -i cc=bb
方法2:expr或let数值运算工具
[root@localhost ~]#aa=11
[root@localhost ~]#bb=22
#给变量aa和变量bb赋值
[root@localhost ~]#dd=$(expr $aa + $bb)
#dd的值是aa和bb的和。注意“+”号左右两侧必须有空格
方法3:“[运算式]”
[root@localhost ~]#aa=11
[root@localhost ~]#bb=22
[root@localhost ~]#ff=aa+$bb))[root@localhost ~]#gg=aa+$bb]
6、变量测试与内容替换
[root@localhost ~]#unset y
#删除变量
[root@localhost ~]#x=${y-new}
#进行测试
[root@localhost ~]#echo $x
new
#因为变量y不存在,所以x=new
(二)、shell语法
1、正则表达式
基础正则表达式
2、字符截取命令
字段提取命令 cut
[root@localhost ~]#cut [选项] 文件名
选项:
-f 列号: 提取第几列
-d 分隔符: 按照指定分隔符分隔列
printf命令
printf ‘输出类型输出格式’ 输出内容
输出类型:
%ns: 输出字符串。n是数字指输出几个字符
%ni: 输出整数。n是数字指代输出几个数字
%m.nf: 输出浮点数。m和n是数字,指代输出的整数位数和小数位数。如%8.2f共输出8位数,其中2位是小数,6位是整数。
输出格式:
\a: 输出警告声音
\b: 输出退格键,也就是Backspace键
\f: 清楚屏幕
\n: 换行
\r: 回车,也就是Enter键
\t: 水平输出退格键,也就是Tab键
\v: 垂直输出退格键,也就是Tab键
在awk命令的输出中支持print和pintf命令
· print:print会在每个输出之后自动加入一个换行符(Linux默认没有print命令)
· printf:printf是标准格式输出命令,并不会自动加入换行符,如果需要换行,需要手工加入换行符
#awk ‘{printf $2 “\t” $6 “\n”}’ student.txt
#df -h | awk ‘print $1 “\t” $3’
sed命令
sed是一种几乎包括在所有UNIX平台(包括Linux)的轻量级流编辑器。sed主要是用来将数据进行选取、替换、删除、新增的命令。
[root@localhost ~]#sed [选项] ‘[动作]’ 文件名
选项:
-n: 一般sed命令会把所有数据都输出到屏幕,如果加入此选择,则只会把经过sed命令处理的行输出到屏幕
-e: 允许对输入数据应用多条sed命令编辑
-i: 用sed的修改结果直接修改读取数据的文件,而不是由屏幕输出。
动作:
a \: 追加,在当前行后添加一行或多行。添加多行时,除最后一行外,每行末尾需要用“\”代表数据未完结。
c \: 行替换,用c后面的字符串替换原数据行,替换多行时,除最后一行外,每行末尾需用“\”代表数据未完结
o \: 插入,在当期行前插入一行或多行。插入多行时,除最后一行外,每行末尾需要用“\”代表数据未完结。
d: 删除,删除指定的行。
p: 打印,输出指定的行
s: 字串替换,用一个字符串替换另外一个字符串。格式为“行范围s/旧字串/新字串/g”(和vim中的替换格式类似)。
eg: [root@localhost ~]#sed ‘2p’ student.txt
#查看文件的第二行
[root@localhost ~]#sed -n ‘2p’ student.txt
[root@localhost ~]#sed ‘2,4d’ student.txt
#删除第二行到第四行的数据,但不修改文件本身
[root@localhost ~]#sed ‘2a hello’ student.txt
#在第二行后追加hello
[root@localhost ~]#sed ‘2i hello’ \
world` student.txt
#在第二行前插入两行数据
#sed ‘2c No such person’ student.txt
#数据替换
3、字符处理命令
排序命令 sort
[root@localhost ~]#sort [选项] 文件名
选项:
-f: 忽略大小写
-n: 以数值型进行排序,默认使用字符串型排序
-r: 反向排序
-t: 指定分隔符,默认是分隔符是制表符
-k n[,m]:按照指定的字符范围排序。从第n字段开始,m字段结束(默认到行尾)
[root@localhost ~]#sort /etc/passwd
#排序用户信息文件
[root@localhost ~]#sort -r /etc/passwd
#反向排序
[root@localhost ~]#sort -t “:” -k 3,3 /etc/passwd
#指定分隔符是“:”,用第三字段开头,第三字段结尾排序,就是只用第三字段排序
4、条件判断
1、按照文件类型进行判断
[root@localhost ~]#test -e /root/install.log
[root@localhost ~]#[-e /root/install.log]
[-d /root]&& echo “yes” || echo “no”
#第一个判断命令如果正确执行,则打印“yes”,否则则打印“no”
2、按照文件权限进行判断
3、两个文件之间进行比较
4、两个整数之间比较
5、字符串的判断
aa=11
bb=22
#给变量aa和变量bb赋值
["$aa"==“bb”]&& echo “yes” || echo “no” 返回no
#判断两个变量的值是否相等,明显不相等,所以返回no。
6、多重条件判断
5、流程控制
if语句
1、单分支if条件语句
if [ 条件判断式 ];then
程序
fi
或者
if [ 条件判断式 ]
then
程序
fi
单分支条件语句需要注意几个点
· if语句使用fi结尾,和一般语言使用大括号结尾不同
· [ 条件判断式 ]就是使用test命令判断,所以中括号和条件判断式之间必须有空额
· then后面跟符合条件之后执行的程序,可以放在[]之后,用“:”分割。也可以换行写入,就不需要“:”了。
2、双分支if条件语句
if [条件判断式]
then
条件成立时,执行的程序
else
条件不成立时,执行的另一个程序
fi
case语句
多分支case条件语句
· case语句和if…elif…else语句一样都是多分支条件语句,不过和if多分支条件语句不同的是,case语句只能判断一种条件关系,而if语句可以判断多种条件关系。
case $变量名 in
“值1”)
如果变量的值等于值1,则执行程序1
;;
“值2”)
如果变量的值等于值2,则执行程序2
;;
…省略其他分支…
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
for循环
语法一
for 变量 in 值1 值2 值3…
do
程序
done
语法二
for((初始值;循环控制条件;变量变化))
do
程序
done
while循环
while循环是不定循环,也称作条件循环。只要条件判断式成立,循环就会一直继续,直到条件判断式不成立,循环才会停止。这就和for的固定循环不太一样了。
while [条件判断式]
do
程序
done
until循环,和while循环相反,until循环时只要条件判断式不成立则进行循环,并执行循环程序。一旦循环条件成立,则终止循环。