以下内容主要来自于博客,我只是用作于快速入门,侵权删 (19条消息) Shell笔记_doordiey的博客-CSDN博客
视频学习参考资料24_尚硅谷_Shell_Awk案例_哔哩哔哩_bilibili
概述
Shell是一个命令行解释器,它接受应用程序/用户命令,然后调用操作系统内核

解析器类型
1 2 3 4 5
| [root@ecs-868f-0003 /] /bin/sh /bin/bash /usr/bin/sh /usr/bin/bash
|
- 我们在日常使用最多的就是sh和bash
- sh
- bash
- nologin
- dash
- tcsh
- csh
其中,sh软链接到bash, centos默认解析器是bash
Shell脚本入门
脚本格式
脚本开头指定解析器
一个输出hello,word的脚本 1.sh
1 2
| #!/bin/bash echo hello,word
|
执行脚本
1 2 3 4 5
| bash 1.sh ---方法1 sh 1.sh ----方法2 source 1.sh ----方法3
./1.sh ----方法4,需要给权限,chmod 777 1.sh
|
多命令行例子
在指定目录/a
下创建一个hey.txt, 在hey.txt 中增加hello
1 2 3 4
| #!/bin/bash cd /a touch hey.txt echo hello >> hey.txt
|
变量
系统变量
- 定义变量:变量=值
- 撤销变量: unset变量
- 声明静态变量: readonly 变量,不能unset
变量定义规则
- 可以由字母、数字和下划线组成,不能以数字开头,环境变量名建议大写
- 等号两侧不能有空格
- 在bash中,变量默认类型是字符串类型,无法直接进行数值运算
- 变量的值如果有空格,需要用双引号或者单引号
- 可把变量提升为全局环境变量,使用export 变量名
特殊变量
$n
n为数字,$n表示该脚本名称,$1-$9表示第一到第九个参数,10以上的参数要用大括号括起来
此处参数表示执行脚本时的参数
演示 3.sh
- 执行
3.sh
,执行 sh 3.sh ni hao ma
- 3.sh ni hao (第一个参数是脚本名本身)
$#
获取所有输入参数个数
演示 4.sh
1 2 3 4
| echo "$0 $1 $2" echo $# 123
|
∗,@
$*: 代表命令行中所有的参数,把所有参数看成一个整体
$@:代表命令行中所有的参数,把每个参数区分对待
$?
最后一次执行的命令的返回状态,如果该变量的值为0,说明上一次正确执行了,如果返回非0的数字说明没有正确执行。
下面是命令的演示:
1 2 3 4 5
| #!/bin/bash echo "$1 $2 $3" echo $# echo $* echo $@
|
1 2 3 4 5 6 7
| [root@ecs-868f-0003 a] ni hao ma 3 ni hao ma ni hao ma [root@ecs-868f-0003 a] 0
|
运算符
- ( ( 运 算 式 ) ) 或 者 ((运算式))或者((运算式))或者[运算式]
- expr +,-,*,/, %
- expr运算符间要有空格
演示
1 2
| expr 2 + 3 expr `expr 2 + 3` \* 4
|
条件判断
基本语法
[ condition ] condition前后要有空格
,条件非空即为true
常用判断条件
整数比较
1 2 3 4 5 6 7
| = 字符串比较 -lt 小于 -le 小于等于 -eq 等于 -gt 大于 -ge 大于等于 -ne 不等于
|
文件权限判断
1 2 3 4
| -r 读 -w 写 -x 执行 [ -w 1.sh ] echo $? 1
|
文件类型判断
1 2 3 4
| -f 文件存在且是一个常规文件(file) -e 文件存在(exist) -d 文件存在且是一个文件夹 [ -e 2.sh ] echo $? 1
|
if判断
语法
1 2 3 4 5 6 7 8 9 10 11
| #其中;隔开两个语句 if [ 条件判断式 ]; then xxxx fi
or
if [ 条件判断式 ] then 程序 fi
|
注意事项:
- [ 条件判断式 ], 括号与条件判断式之间必须有空格
- if 后要有空格
实操
输入一个数字,如果输入1,输出banzhang zhen shuai,如果输入2,输出 jjyaoao yyds,如果是其他,则什么也不输出
1 2 3 4 5 6 7
| #!/bin/bash
if [ $1 -eq 1 ]; then echo "banzhang zhen shuai" elif [ $1 -eq 2 ]; then echo "jjyaoao yyds" fi
|
case语句
语法
1 2 3 4 5 6 7 8 9 10 11
| case $变量名 in "值1") xxxx ;; "值2") xxxxx ;; ............. *) 别的都不执行执行这个 esac
|
实操
需求:输入一个数字,如果是1,则输出jjyaoao
,如果是2,则输出hahahaha
,输入其他则输出remake
1 2 3 4 5 6 7 8 9 10 11 12 13
| #!/bin/sh
case $1 in 1) echo jjyaoao ;; 2) echo hahahaha ;; *) echo remake ;; esac
|
1 2 3 4 5 6
| [root@ecs-868f-0003 a] jjyaoao [root@ecs-868f-0003 a] hahahaha [root@ecs-868f-0003 a] remake
|
for循环
语法
1 2 3 4 5 6 7 8 9 10
| for (( 初始值;循环控制条件;变量变化 )) do xxxxx done or for 变量 in 值1 值2 值3 ... do xxxx done
|
练习
计算1-100累加
1 2 3 4 5 6 7 8
| #!/bin/sh
ans=0 for((i=1;i<=100;i++)) do ans=$[ $ans + $i ] done echo $ans
|
1 2
| [root@ecs-868f-0003 a] 5050
|
打印所有输入参数
1 2 3 4 5 6
| #!/bin/sh
for i in $* do echo "jjyaoao like $i" done
|
1 2 3
| [root@ecs-868f-0003 a] jjyaoao like crystal jjyaoao like gala
|
#@
与#*
的区别
如果取消” “的话也没有区别,” “才可以将空格都连接起来。
1 2 3 4 5 6 7 8 9 10 11
| #!/bin/sh
for i in "$*" do echo "jjyaoao like $i" done
for i in "$@" do echo "jjyaoao like $i" done
|
1 2 3 4
| [root@ecs-868f-0003 a] jjyaoao like crystal gala jjyaoao like crystal jjyaoao like gala
|
while 循环
语法
1 2 3 4
| while [ condition ] do xxx done
|
1 2 3 4 5 6 7 8 9
| #!bin/bash s=0 i=1 while [ $i -le 100 ] do s=$[$s + $i] i=$[$i + 1] done echo $s
|
read读取控制台输出
语法
- 选项:
- -p: 指定读取值时的提示符(返回在命令行的提示语句
- -t:指定读取值时等待的事件(秒)
- 参数
举例
提示12秒内,读取控制台输入的名称
1 2 3
| #!bin/bash read -t 12 -p "你的名字是" Word echo $Word
|
1 2 3
| [root@ecs-868f-0003 a]# sh read.sh 你的名字是jjyaoao jjyaoao
|
函数
系统函数
basename
语法
1
| basename [string/ pathname][suffix]
|
- 命令会删除所有的后缀包括最后一个/字符的然后输出字符串
- 选项:suffix 为后缀,可以把后缀给去了
- 用来获取文件名
dirname
语法
- dirname 文件绝对路径, 从给定的包含绝对路径的文件名中去除文件名,然后返回剩下的路径
1 2 3 4 5 6
| [root@ecs-868f-0003 a] read.sh [root@ecs-868f-0003 a] read [root@ecs-868f-0003 a] /a
|
自定义函数
语法
1 2 3 4 5 6
| [ function ] funname[()]{ Action; [return int;] }
funname
|
- 调用函数地方之间要先声明函数
- 函数返回值,只能通过$?系统变量获得,可以显示加:return 返回,如果不加,将最后一条命令运行结果做为返回值
练习
计算两个输入参数的和
1 2 3 4 5 6 7 8 9 10 11 12
| #!/bin/sh
function sum(){ s=0; s=$[ $1 + $2 ] echo $s }
read -p "input your paratemer1:" p1 read -p "input your paratemer2:" p2
sum $p1 $p2
|
1 2 3 4
| [root@ecs-868f-0003 a] input your paratemer1:23 input your paratemer2:45 68
|
Shell工具
cut
在文件中剪切数据用,从文件中的每一行剪切字节、字符和字段并将这些字节、字符和字段输出
基本用法
- 默认分隔符是制表符
- 选项参数
- -f 列号: 提取第几列
- -d 分隔符,按照指定分隔符分割
举例
1
| # test.txt文件内容如下1 y2 i3 j4 o8 l
|
1 2
| [root@ecs-868f-0003 a]# ifconfig eth0 | grep "inet " inet 192.168.0.194 netmask 255.255.255.0 broadcast 192.168.0.255
|
1 2
| [root@ecs-868f-0003 a] 192.168.0.194
|
最终得到IP地址
sed
一种流编辑器,一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为模式空间,sed命令处理缓冲区中的内容,处理完成后,把内容送往屏幕,接着处理下一行,不断重复。文件内容不改变,除非你使用重定向存储输出。
基本用法
1 2
| sed [选项参数] `command` filename 1
|
下面将用这串文字进行演示
1 2 3 4 5 6 7 8
| # sed.txt dong shen guan zhen mei nv wo wo lai lai
le le
|
打印时在第二行增加字段 00 hj
删除包含wo的行
替换wo为ni
打印时在第二行增加字段 00 hj 替换wo为ni
注意:如果有多行命令需要在命令行执行,那就-e xxx -e xxx
1
| sed -e '2a 00 hj' -e 's/wo/ni/g' sed.txt
|
awk
强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。
基本用法
1
| awk [选项参数] 'pattern1{action1}' filename
|
- pattern:表示awk再数据中查找的内容
- action:找到匹配内容时执行命令
- 选项参数
- -F:指定输入文件分隔符
- -v 赋值一个用户定义变量
举例
内置变量
- filename 文件名
- nr 已读的记录数
- nf 浏览记录的域的个数
练习
数据准备
1 2 3 4 5 6
| [root@ecs-868f-0003 a] root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin ..................... chrony:x:998:996::/var/lib/chrony:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin
|
/^root 为正则表达式定位开头
要求:只显示passwd文件的第一列和第七列,以逗号分隔,且在所有航前面添加列名user, shell
在最后一行添加”jjyaoao /bin/yyds”
BEGIN为正则条件
1 2
| [root@ecs-868f-0003 a] END{print "jjyaoao /bin/yyds"}' passwd
|
1 2 3 4 5 6 7
| user, shell root,/bin/bash bin,/sbin/nologin ................ chrony,/sbin/nologin tcpdump,/sbin/nologin jjyaoao /bin/yyds
|
要求:将passwd文件中用户id增加数值 1 并输出
ps:环境变量就是:切分的第三个
1 2 3 4 5 6
| [root@ecs-868f-0003 a]# awk -F : -v i=1 '{print $3+i}' passwd 1 2 ................. 999 73
|
注意:这里面$3 + i
,而不是 $3 + $i
,=-=其实我也不知道为什么
sort
文件排序
基本用法
- 选项
- -n 按照数值大小排序
- -r 以相反的顺序排序
- -t 设置排序使用的分隔字符
- -k 指定需要排序的列
- 参数
练习
1 2 3 4 5 6
| bb:40:5.4 bd:20:4.2 xz:50:2.3 cls:10:3.5 jjyaoao:99:1.6
|
1 2 3 4 5 6
| [root@ecs-868f-0003 a] jjyaoao:99:1.6 xz:50:2.3 bb:40:5.4 bd:20:4.2 cls:10:3.5
|
企业面试题

注意点: /^$就是空行

-f 为检测文件是否存在


就考你知不知道sort命令
金和网络:
请用shell脚本写出查找当前文件夹(/a)下所有文本文件内容中包含有字符”shen”的文件名称
1 2 3 4 5 6
| [root@ecs-868f-0003 a] sed.txt:dong shen [root@ecs-868f-0003 a] /a/sed.txt:dong shen [root@ecs-868f-0003 a] /a/sed.txt
|
The end.