文章目录
第一章 shell 的概述
Shell是一个命令行的解释器:bash、sh等
用于接收应用程序/用户命令,然后调用操作系统内核(用户与内核进行交互)
=》硬件 -》 Linux 内核 -》 shell (cd、 ls) -》 外层应用程序
shell 程序的特点:
功能相当强大的编程语言,易编写、易调试、灵活性强。
对手: python
第二章 shell 脚本入门
- 脚本设计及运行
vim first_shell.sh =>创建文件并编写
脚本以#!/bin/bash 开头(指定解析器)
案例实操:
#!/bin/bash
echo “helloworld”
修改权限 chmod +x first_shell.sh 等价于 chmod 777 first_shell.sh
执行脚本 相对路径:./first_shell.sh 绝对路径: bash /mnt/share/first_shell.sh
-
注释
单行注释:以#开头
多行注释:
:<<EOF
注释多行
EOF -
多命令处理:
在 /home/atguigu/目录下创建一个banzhang.txt,在banzhang.txt 文件中增加 “I love cls”。
#!/bin/bash
cd /home/atguigu/ #跳转目录
touch banzhang.txt #创建一个文件,并命名为banzhang.txt
echo “I love cls” >> banzhang.txt #将I love cls 追加至banzhang.txt
标准输入与输出的重定向(>、>>、2>、2>>、&>)
2> 重定向错误信息
2>> 追加错误信息
&> 错误信息和正确信息都导入(覆盖)
第三章 shell 变量
根据变量的作用域,变量可以分为本地变量和环境变量
本地变量只在创建它们的 shell 程序中可用
环境变量则在shell 中的所有用户进程中可用,也称为全局变量
- 系统变量
常用系统变量
H O M E 、 HOME、 HOME、PWD、 S H E L L 、 SHELL、 SHELL、USER 等
查看系统变量的值
echo $HOME
=》/home/atguigu
- 自定义变量
定义变量的格式:变量名=变量值
取消变量的格式:unset 变量名
只读变量的格式:readonly 变量=变量值(注意;不能unset)
可把变量提升为全局环境变量:export 变量名,例export Y=22
注意事项:
(1)A=2 (等号两边不能有空格),不要使用关键字做变量名
(2)如果变量名已经存在则覆盖之前的变量值
(3)变量名称由字母/数字/下划线组成,不能以数字开头
(4) 在bash 中, 变量默认类型都是字符串类型,无法直接进行数值运算
(5)变量的值如果有空格,需要使用双引号或单引号括起来
-
位置变量
$1、 2 … … 、 2……、 2……、{10} 参数项 => (10个以上的参数需要用大括号包含) -
预定义变量
$0 当前所在的进程或脚本名
$$ 当前运行进程的PID 号
$? 最后一次执行的命令的返回状态。如果这个变量的值为0, 证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数, 由命令自己来决定),则证明上一个命令执行不正确了
$# 已加载的位置变量的个数
$* 所有位置变量的值
变量扩展应用
双引号 “” 可拓展
单引号 ‘’ 会屏蔽特殊符号的含义
反引号 ` 将命令的执行输出作为变量值,$() 与反引号等效
反引号实例:
grep root /etc/passwd
=> root:x:0:0:root:/root:/bin/bash
test=`grep root /etc/passwd`
echo $test
=> root:x:0:0:root:/root:/bin/bash
第四章 shell 字符串
拼接字符串
first=“hello”
second=“world”
echo $first $second #输出hello world
查找子字符串
#功能描述:查找i / o 的位置
str=“runoob is a great site”
echo expr index "$str" io
#输出 4
获取字符串长度
str=“abcd”
echo ${#str} #输出 4
提取子字符串
#功能描述:从第二个字符开始截取四个字符
str=“runoob is a great site”
echo ${str:1:4} #输出 unoo
子串的截取
phone=18152692171
echo ${#phone} => 11
echo ${phone:0:3} =>181
echo ${phone:3:3} =>526
echo ${phone:4} =>2692171
echo ${phone:4:-2} =>26921
子串的替换
替换一个
${变量/旧字串/新字串}
替换全部结果
${变量/旧字串//新字串}
字串掐头
从左向右,最短匹配删除
${变量#关键词} #删除关键词从左往右的字串
从左向右,最长匹配删除
${变量##关键词}
字串去尾
从右向左,最短匹配删除
${变量%关键词} #删除关键词从右向左的字串
从右向左,最长匹配删除
${变量%%关键词}
批量修改文件拓展名
touch {a,b,c,d,e,f}.txt
vim rename.sh
#!/bin/bash
for i in $(ls *.txt)
do
mv $i ${i%.*}.doc
done
第五章 shell 数组
格式:数组名=(值1 值2 … 值n)
读取数组 ${数组名[下标]}
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}
第六章 shell 运算符
- 算术运算符(加+、减-、乘*、除/、取余%、赋值=、相等==、不相等!=)
实例:
#!/bin/bash
a=10
b=20
val=`expr $a + $b`
echo "a + b : $val"
- 关系运算符
-eq 是否相等
-ne 是否不等
-gt 是否大于
-lt 是否小于
-ge 是否大于等于
-le 是否小于等于
实例:
#!/bin/bash
a=10
b=20
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等于 b"
else
echo "$a -eq $b: a 不等于 b"
- 布尔运算符
! 非
-o 或
-a 与
实例:
#!/bin/bash
a=10
b=20
if [ $a -lt 100 -o $b -gt 100 ]
then
echo "$a 小于 100 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 100 或 $b 大于 100 : 返回 false"
- 逻辑运算符
&& 与
|| 或
实例:
#!/bin/bash
a=10
b=20
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
- 文件测试运算符
-d 是否是目录
-f 是否是普通文件
-r 是否可读
-w 是否可写
-x 是否可执行
-s 是否为空
-e 是否存在
实例:
#!/bin/bash
file="/var/www/runoob/test.sh"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
拓展:shell printf 命令
printf “%-10s %-8s %-4s\n” 姓名 性别 体重kg
printf “%-10s %-8s %-4.2f\n” 郭靖 男 66.1234
=》姓名 性别 体重kg
=》郭靖 男 66.12
第七章 shell 分支语句
if 判断
1、基本语法
if [ 条件判断式 ];then
程序
fi
或者
if [ 条件判断式 ]
then
程序
fi
注意事项:
(1)[ 条件判断式 ],中括号和条件判断式之间必须有空格
(2) if 后要有空格
2、案例实操
(1) 输入一个数字,如果是1 , 则输出 banzhang zhen shuai,如果是2, 则输出 cls zhen mei, 如果是其它,什么也不输出
#!/bin/bash
if [ $1 -eq “1” ]
then
echo “banzhang zhen shuai”
elif [ $1 -eq “2” ]
then
echo “cls zhen mei”
fi
case 语句
1、基本语法
case $变量名 in
“值 1”)
如果变量的值等于值1,则执行程序1
;;
“值 2”)
如果变量的值等于值2,则执行程序2
;;
……省略其他分支……
)
如果变量的值都不是以上的值,则执行此程序
;;
注意事项:
1)case 行尾必须为单词 “in” ,每一个模式匹配必须以有括号 “)”结束
2)双分号 “;;” 表示命令序列结束,相当于Java 中的break
3)最后的 “)” 表示默认模式,相对于Java中的default
2、案例实操
(1)输入一个数字,如果是1, 则输出 banzhang,如果是2,则输出cls,如果是其他,输出renyao
#!/bin/bash
case $1 in
1)
echo “banzhang”
;;
2)
echo “cls”
;;
*)
echo “renyao”
;;
esac
#!/bin/bash
#菜单选择
clear
echo -e "\033[42m------------------\033[0m"
echo -e "#\e[32m 1、查看网卡信息\e[0m #"
echo -e "#\e[33m 2、查看内存信息\e[0m #"
echo -e "#\e[34m 3、查看磁盘信息\e[0m #"
echo -e "\033[42m------------------\033[0m"
echo
read -p "please input your key:" key
case $key in
1)
ifconfig | head -2;;
2)
echo "本机内存为:";;
3)
echo "本机容量为:";;
*)
echo "error";;
esac
组合命令:
; =》 cd /etc;ls # 书写在一行,用分号隔开
&& =》如果前面条件执行失败,后面的条件就没必要执行了,惰性
|| =》 如果前面条件执行成功,后面的条件也没必要执行了
第八章 shell 循环控制
for 循环
1、基本语法
for((初始值;循环控制条件;变量变化))
do
程序
done
2、案例实操
(1)从1加到100
#!/bin/bash
s=0
for((i=0;i<=100;++i))
do
s=
[
[
[s+$i]
done
echo $s
=========================
3、基本语法
for 变量 in 值1 值2 值3 ……
do
程序
done
4、案例实操
#!/bin/bash
for i in $*
do
echo "ban zhang love $i "
done
$@ 一次一个
$* 作为一个整体
while 循环
1、基本语法
whiel [ 条件判断式 ]
do
程序
done
2、案例实操
#!/bin/bash
#功能描述:从1 加到 100
s=0
i=1
while [
i
−
l
e
100
]
d
o
s
=
i -le 100] do s=
i−le100]dos=[
s
+
s+
s+i]
i=
[
[
[i+1]
done
echo $s
第九章 read 读取控制台输入
1、基本语法
read(选项)(参数)
选项:
-p: 指定读取值时的提示符
-t:指定读取值时等待的时间(秒)
参数
变量: 指定读取值的变量名
2、案例实操
(1)提示7 秒内,读取控制台输入的名称
#!/bin/bash
read -t 7 -p "Enter your name in 7 seconds " NAME
echo $NAME
(2)给变量赋值
read 从键盘读入变量值完成赋值
格式:read [-p "提示信息"] 变量名
实例:
vim read.sh
#!/bin/bash
read -p "请输入用户名:" name
read -p "请输入密码:" -t 3 -s pass
第十章 shell 函数
1、系统函数
1)basename 基本语法
basename [string /pathname][suffix] (功能描述:basename 命令会删掉所有的前缀包括最后一个 (‘/’)字符,然后将字符串显示出来)
选项:
suffix 为后缀, 如果 suffix被指定了,basename 会将pathname 或 string 中的 suffix 去掉
2)案例实操
basename /home/atguigu/banzhang.txt
banzhang.txt
basename /home/atguigu/banzhang.txt .txt
banzhang
3)dirname 基本语法
dirname 文件绝对路径 (功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录部分),然后返回剩下的路径(目录部分))
4)实操
获取 banzhang.txt 文件路径
dirname /home/atguigu/banzhang.txt
/home/atguigu
2、自定义函数
1、基本语法
[ function] funname[()]
{
Action;
[return int;]
}
2、经验技巧
(1)必须在调用函数地方之前,先声明函数,shell 脚本 是逐行运行。不会像其他语言一样先编译。
(2)函数返回值,只能通过 $? 系统变量获得,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值,return 后跟数值 n(0 - 255)
3、案例实操
(1)计算两个输入参数的和
touch fun.sh
vim fun.sh
#!/bin/bash
function sum()
{
s=0
s=$[ $1 +
2
]
e
c
h
o
"
2] echo "
2]echo"s"
}
read -p “Please input the number1:” n1;
read -p “Please input the number2:” n2;
sum $n1 $n2;
第十一章 shell 工具(重点)
1、cut
cut 的工具就是“剪”,具体的说就是在文件中负责剪切数据用的,cut 命令 从文件的每一行剪切字节,字符和字段并将这些字节,字符和字段输出。
1、基本用法
cut [选项参数] filename
说明:默认分隔符是制表符
2、选项参数说明
-f 列号,提取第几列
-d 分隔符,按照指定分隔符分隔列
3、案例实操
touch cut.txt
vim cut.txt
dong shen
guan zhen
wo wo
lai lai
le le
cut -d " " -f 1 cut.txt
dong
guan
wo
lai
le
cut -d " " -f 2,3 cut.txt
shen
zhen
wo
lai
le
正则表达式
在cut.txt 文件中切割出 guan
cat cut.txt | grep guan | cut -d " " -f 1
guan zhen => guan
选取系统PATH 变量值,第2个“,” 开始后的所有路径:
echo $PATH
/usr/lib64/qt-3.3/bin/:/usr/local/bin/:/bin:……
echo $PATH | cut -d : -f 3- #代表第三列之后所有的
ifconfig 查看IP 地址
2、sed
sed 是一种流编辑器,它一次处理一行内容,处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”, 接着用sed 命令处理器缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,知道文件末尾,文件内容并没有改变,除非你使用重定向存储输出。
1、基本用法
sed [选项参数] ‘command’ filename
2、常用选项:
-n : 屏蔽默认输出
-i : 直接修改源文件
-r : 支持扩展正则
sed -n ‘1,3p’ /etc/passwd # -n 屏蔽默认输出 , 打印 1至3行
sed -n ‘3p’ /etc/passwd #打印第3行
sed -n ‘1,3p’ /etc/passwd #打印1到3行
sed -n ‘1~2p’ /etc/passwd #第1行开始,步长为2
sed -n ‘2~2p’ /etc/passwd #第2行开始,步长为2
sed -n ‘2,+3p’ /etc/passwd #第2行以及后面的3行
正则定位:
grep ^root /etc/passwd #过滤root 开头的行
sed -n ‘/^root/p’ /etc/passwd
grep “[0-9]{3}” /etc/passwd #过滤包含3个数字的行
sed -rn ‘/[0-9]{3}/p’ /etc/passwd
3、使用sed 修改配置
p(print):打印行
sed -n ‘1p;3p;6p’ /etc/passwd #显示第1、3、6行内容
sed -n ‘2!p’ /etc/hosts #打印第2行以外的所有其他行内容
d(delete):删除行
sed ‘/^$/d’ /tmp/fstab #删除空白行
sed ‘d’ /etc/hosts #删除所有行
c(replace):替换行
sed ‘c 123456’ /tmp/fstab #所有行替换为123456
file=/etc/sysconfig/network-scripts/ifcfg-eth0
sed ‘IPADDR/c IPADDR=1.1.1.1’ $file #替换IP地址
s(subsitution):替换关键词
sed ‘s/2046/xxxx/’ test.txt #替换第一个(默认)
sed ‘s/2046/xxxx/g’ test.txt #替换全部
sed ‘s/2046/xxxx/2’ test.txt #替换第二个
sed ‘s/2046/(&)/g’ test.txt # &表示老的内容2046
sed ‘2s/2046/xxxx/g’ test.txt #只替换第二行的2046
sed ‘2s/2046//g’ test.txt #将第二行的2046清空
sed ‘2s/2046/xxxx/p’ test.txt #把第二行的2046替换为xxxx,并将结果打印出来
echo "hello the world" | sed -r 's/^(.)(.*)(.)$/\3\2\1/'
=:打印行号
sed -n ‘/bash/=’ /etc/passwd
sed -n ‘$=’ /etc/passwd #打印总共有多少行
4、sed 多行文本处理
i(insert):插入
sed ‘2i ABC_XYZ’ test.txt #在第二行前面加ABC_XYZ
sed ‘/2046/i ABC\nXYZ’ test.txt #包含2046的行 前面加ABC_XYZ
a(append):追加
sed ‘2a ABC_XYZ’ test.txt
sed ‘/2046/a ABC\nXYZ’ test.txt
r(read):读取文件|导入文件内容
sed ‘2r /etc/hosts’ test.txt
sed ‘r /etc/hosts’ test.txt
sed ‘/1888/r /etc/hosts’ test.txt
w(write):文件另存为|导出文件内容
sed ‘/1888/w 1888.txt’ test.txt
5、案例实操
================================================
touch sed.txt
vim sed.txt
dong shen
guan zhen
wo wo
lai lai
le le
将 “mei nv” 这个单词插入到sed.txt 第二行下,打印
sed ‘2a mei nv’ sed.txt
注意:文件并没有改变
=================================================
删除sed.txt 文件所有包含 wo 的行
sed ‘/wo/d’ sed.txt
dong shen
guan zhen
lai lai
le le
==================================================
vim /root/shell/day04/roll.sh
#!/bin/bash
#功能描述(description):随机筛选名字
name_file=“name.txt”
line_file=
(
s
e
d
−
n
′
(sed -n '
(sed−n′=’ $name_file)
while :
do
clear
tmp=
(
s
e
d
−
n
"
(sed -n "
(sed−n"[RANDOM%line_file+1]p" $name_file)
echo -e “\033[32m####################\033[0m”
echo
echo -e “\033[32m $tmp \033[0m”
echo
echo -e “\033[32m####################\033[0m”
sleep 0.1
done
==================================================
3、awk
awk 基础语法
格式1:前置命令 | awk [选项] ‘[条件]{指令}’
格式2:awk [选项] ‘[条件]{指令}’ 文件…
awk '{print $1,$3}' test.txt #打印第一列,第三列
常用选项:-F 可以指定分隔符,默认分隔符为(空格或Tab键)
awk -F: '{print $1,$3}' /etc/passwd
$n 指定分隔的第n个字段,如$1 表示第一列
$0 当前读入的整行文本内容
NF 记录当前处理行的字段个数(列数)
NR 记录当前已读入行的数量(行数)
awk -F: '{print NR,NF}' /etc/passwd
awk -F: '{print $NF}' /etc/passwd
awk -F: '{print "用户名:",$1,"解释器:",$7}' /etc/passwd
可以单独使用,也可以同时一起使用
BEGIN{} #在所有行前处理
{} #逐行处理
END{} #在所有行后处理
awk 'BEGIN {a=34;print a+12}'
awk 'BEGIN {x=0}/\<bash$/{x++}END{print x}' /etc/passwd
awk -F: 'BEGIN {print NR}END{print NR}' /etc/passwd
awk 基础应用案列
数据流量:ifconfig ens33 | grep "RX p" | awk '{print $5}'
<=> ifconfig ens33 | awk '/RX p/{print $5}'
awk 条件判断
awk [选项] '[条件]{指令}' 文件……
条件表达式
正则表达式
数值/字符比较
逻辑比较
awk -F: '/^ro/{print}' /etc/passwd
awk -F: '$7!~/bash$/{print $1,$7}' /etc/passwd
awk 流程控制
awk '{指令}' 文件
awk -F: '{if($3>=1000){i++}} END{print i}' /etc/passwd
awk 'BEGIN{ commands } pattern{ commands } END{ commands }' file
=> awk 'BEGIN{ i=0 } { i++ } END{ print i }' filename
数字、字符比较
==、!=
>、>=
<、<=
awk 'NR==2{print}' /etc/passwd
awk -F: '$7!="/bin/bash"' /etc/passwd
awk -F: '$3>=1000{print $1}' /etc/passwd
awk -F: '$3>=0&&$3<2{print $1,$3}' /etc/passwd
支持for循环,if - else if - else
awk 数组与应用案列
数据名[下标]=元素值
遍历数组:格式 for(变量名 in 数组名){print 数组名[变量]}
awk 'BEGIN{
Array[1]="sun"
Array[2]="kai"
Array["first"]="www"
Array["last"]="name"
Array["birth"]="1987"
info = "it is a test";
lens = split(info,tA," ");
for(item in tA)
{
print tA[item];
}
for(i=1;i<=lens;i++)
{
print tA[i];
}
print length(tA[lens]);
}
{
print "item in array";
or(item in Array)
{
print Array[item]
};
print "print in i++";
for(i=1;i<=length(Array);i++)
{
print Array[i]
};
}'
AWK 内置变量
ARGC:命令行参数的数目
ARGIND:命令行中当前文件的位置(从0开始算)
ARGV:包含命令行参数的数组
CONVFMT:数字转换格式(默认值为%.6g)
ENVIRON:环境变量关联数组
ERRNO:最后一个系统错误的描述
FIELDWIDTHS : 字段宽度列表(用空格键分隔)。
FILENAME : 当前输入文件的名。
FNR : 同NR :,但相对于当前文件。
IGNORECASE : 如果为真,则进行忽略大小写的匹配。
OFMT : 数字的输出格式(默认值是%.6g)。
OFS : 输出字段分隔符(默认值是一个空格)。
ORS : 输出记录分隔符(默认值是一个换行符)。
RS : 记录分隔符(默认是一个换行符)。
RSTART : 由match函数所匹配的字符串的第一个位置。
RLENGTH : 由match函数所匹配的字符串的长度。
SUBSEP : 数组下标分隔符(默认值是34)
4、正则表达式
基本规则:
=》grep “r.*t”
echo “ababab” | grep ab
abc 匹配abc
^ 匹配开头
$ 匹配结尾
[集合] 匹配集合中的任意单个字符
[^集合] 对集合取反
. 匹配任意单个字符
* 匹配前一个字符任意次(包含0次)
.* 匹配任意
\{n,m\} 匹配前一个字符n到m次
\{n,\} 匹配前一个字符至少n次
\{n\} 匹配前一个字符n次
扩展正则:
=》grep -E "0{2,3}"
echo "ababab" | grep -E "(ab){2}"
+ 匹配前面的字符至少一次
? 匹配前面的字符0或1次
() 组合与保留
| 或者
{n,m} 匹配前面的字符n到m次
{n,} 匹配前面的字符至少n次
{n} 匹配前面的字符n次
perl兼容的正则符号
=》grep -P "\bbin\b" /etc/passwd
\b 匹配单词边界
\w 匹配字母数字下划线
\W 和\w相反
\s 匹配空白
\d 匹配数字
\d+ 匹配多个数字
\D 匹配非数字
用法:grep [选项] 匹配模式 [文件]...
常用选项:
-i 忽略大小写
-v 取反匹配
-w 匹配单词
-q 静默匹配,不将结果显示在屏幕
实例:从《python.txt》文件中过滤如下数据:
过滤包含the的行 grep the python.txt
不区分大小写过滤包含the的行 grep -i the python.txt
过滤不包含the的行 grep -E "^(the)" python.txt
过滤包含数字的行 grep "[0-9]" python.txt <=> grep -P "\d" python.txt
过滤包含bet 或 better 的行 grep -E "(bet|better)" python.txt
过滤包含2个字母o的行 grep -E "o{2}" python.txt
过滤包含1-2个字母o的行 grep -E "o{1,2}" python.txt
过滤不包含字母o的行 grep -v "o" python.txt
过滤大写字母开头的行 grep -E "^[A-Z]" python.txt
过滤小写字母开头的行 grep -E "^[a-z]" python.txt
过滤ou 前面不是th的行 grep -E "[^(th)]ou" python.txt
过滤不以标点符号结束的行 grep -P "\W$" python.txt
过滤空白行 grep -E "^$" python.txt
过滤以.结尾的行 grep -E "[^.]$" python.txt
过滤以数字开始的行 grep -E "^[0-9]" python.txt
过滤包含2个以上z的行 grep -E "z{2,}" python.txt
过滤所有字母 grep -E "[a-zA-Z]" python.txt
过滤所有标点符号 grep -P "\W" python.txt
第十二章 实例
https://blog.csdn.net/YHB123___ahnd/article/details/119783004