shell 概述 命令行解释器
硬件 -> Linux 内核 -> shell (cd, ls, …) -> 外层应用程序。
shell 解析器 1 2 3 4 5 6 7 8 9 10 11 12 13 [ec2-user@master bin]$ cat /bin/shell /bin/sh /bin/bash /usr/bin/sh /usr/bin/bash /usr/bin/tmux [ec2-user@master bin]$ ll |grep bash -rwxr-xr-x 1 root root 964608 Oct 31 2018 bash lrwxrwxrwx 1 root root 10 Feb 26 2019 bashbug -> bashbug-64 -rwxr-xr-x 1 root root 6964 Oct 31 2018 bashbug-64 lrwxrwxrwx 1 root root 4 Feb 26 2019 sh -> bash
可以看出sh也用的bash解析器
shell 脚本入门 脚本格式,如下,开头指定解析器,不是注释
初识shell脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 [ec2-user@master test ]$ touch helloworld.sh [ec2-user@master test ]$ vi helloworld.sh #!/bin/bash echo "hello world, ganshizhong" [ec2-user@master test ]$ sh helloworld.sh hello world, ganshizhong [ec2-user@master test ]$ bash helloworld.sh hello world, ganshizhong [ec2-user@master test ]$ ./helloworld.sh -bash: ./helloworld.sh: Permission denied [ec2-user@master test ]$ ll total 4 -rw-rw-r-- 1 ec2-user ec2-user 44 May 30 14:39 helloworld.sh [ec2-user@master test ]$ chmod 777 helloworld.sh [ec2-user@master test ]$ ll total 4 -rwxrwxrwx 1 ec2-user ec2-user 44 May 30 14:39 helloworld.sh [ec2-user@master test ]$ ./helloworld.sh hello world, ganshizhong
例子
1 2 3 4 #!/bin/bash cd /home/ec2-user/test/ touch test1.txt echo "i love you" >> test1.txt
shell中的变量 1. 常用变量: $HOME, $PWD, $SHELL, $USER等 1 echo $HOME , $PWD , $SHELL , $USER
2. 自定义变量
基本语法
定义变量:变量=值
撤销变量:unset 变量
声明静态变量: readonly变量,注意不能unset
变量定义规则
变量可由字母、数字和下划线组成,但不能以数字开头,环境变量建议大写
等号两侧不能有空格
在bash中,变量默认类型都是字符串类型,无法直接进行数值计算
变量的值如果有空格,需要使用双引号或单引号括起来
1 2 3 4 5 6 7 8 9 10 11 12 13 A=1 echo $A unset Areadonly B=3unset B D="I love gsz" echo Dexport 变量名
3. 特殊变量 $n
功能描述:n为数字,$0代表该脚本名称,$1-$9代表第一到第九个参数,十以上的参数需要用大括号,如 ${10}
1 2 3 4 5 6 7 8 9 10 [ec2-user@master test ]$ vi parameter.sh [ec2-user@master test ]$ sh parameter.sh #!/bin/bash echo "$0 " echo "$1 $2 $3 " echo "$@ " echo "$*" [ec2-user@master test ]$ sh parameter.sh gsz a aa aaaa parameter.sh gsz a aa
$#
$ *
功能描述:表示命令行中所有的参数,并把所有参数看作一个整体
$@
功能描述:表示命令行中所有的参数,但区分对待每个参数
$?
功能描述:最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0,则不正确。
运算符 基本语法
“$((运算式))” 或 “$[运算式]”
expr +,-,*,/,% 加减乘除取余
expr运算符间要有空格
1 2 3 4 5 6 7 8 9 [ec2-user@master test ]$ expr 3 + 2 5 [ec2-user@master test ]$ expr `expr 2 + 3` \* 4 20 [ec2-user@master test ]$ expr `expr 2 + 3` \* 4 20 [ec2-user@master test ]$ s=$[(2+3)*4] [ec2-user@master test ]$ echo $s 20
条件判断
基本语法
[ condition ]
注意前后要有空格 ,条件非空即为true,[atguigu]返回true,[]返回false.
常用判断条件
两个整数之间比较
=字符串比较
-lt 小于(less than)
-le 小于等于(less equal)
-eq 等于(equal)
-gt 大于(greater than)
-ge 大于等于(greater equal)
-ne 不等于(not equal)
按照文件权限进行判断
-r 有读写权限(read)
-w 有写的权限(write)
-x 有执行的权限(execute)
按照文件类型进行判断
-f 文件存在且是一个常规的文件(file)
-e 文件存在(existence)
-d 文件存在并且是一个目录(directory)
多条件判断
&& 表示前面一条执行成功,才执行后一条命令
|| 表示上一条命令执行失败后,才执行下一条命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [ec2-user@master test ]$ [23 -ge 22] -bash: [23: command not found [ec2-user@master test ]$ [ 23 -ge 22 ] [ec2-user@master test ]$ echo $? 0 [ec2-user@master test ]$ [ 23 -le 22 ] [ec2-user@master test ]$ echo $? 1 [ec2-user@master test ]$ [ -w helloworld.sh ] [ec2-user@master test ]$ echo $? 0 [ec2-user@master test ]$ [ 23 -ge 22 ] && echo ok ok [ec2-user@master test ]$ [ 23 -ge 22 ] && [ ] || echo notok notok
流程控制(重点) if 判断
基本语法1 2 3 4 5 6 7 8 9 if [ 条件判断式子 ];then 程序 elif fi if [ 条件判断式 ]then 程序 if
if后必须有空格
例子1 2 3 4 5 6 #!/bin/bash if [ $1 -eq 1 ];then echo "ganshizhong is handsome" elif [ $1 -eq 2 ];then echo "ganshizhong" if
case 语句
基本语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #!/bin/bash case 值 in 模式1) command1 command2 ... commandN ;; 模式2) command1 command2 ... commandN ;; esac
例子
1 2 3 4 5 6 7 8 9 10 11 #!/bin/bash case $1 in 1) echo "print 1" ;; 2) echo "print 2" ;; *) echo "print other" esac
for 循环
基本语法
1 2 3 4 for ((初始值;循环控制条件;变量变化))do 程序 done
例子
1 2 3 4 5 6 7 #!/bin/bash s=0 for ((i=1;i<=100;i++))do s=$[$s +$i ] done echo $s
1 2 3 4 5 6 7 8 9 10 11 #!/bin/bash s=0 for i in $*do echo $i done [ec2-user@master test ]$ sh for2.sh 1 2 23 1 2 23
1 2 3 4 5 6 7 8 9 10 11 #!/bin/bash s=0 for i in "$@ " do echo $i done [ec2-user@master test ]$ sh for2.sh "1 2 23" 1 2 23
此处应该注意’$*’和’$@’之间的区别
while循环
基本语法
1 2 3 4 while [ 条件判断式 ]do 程序 done
例子
1 2 3 4 5 6 7 8 9 s=0 i=1 while [ $i -le 100 ]do s=$[$i +$s ] i=$[$i +1] done echo $s
条件中 只能用 -le 不能用 <=
read读取控制台输入
基本语法
1 2 3 4 5 6 read (选项)(参数)选项: -p: 指定读取值时的提示符 -t: 指定读取值时等待的时间(秒) 参数: 变量:指定读取值的变量名
例子
1 2 3 4 5 6 7 read -t 7 -p "Enter your name in 7 seconds: " NAMEecho $NAME [ec2-user@master test ]$ sh read.sh Enter your name in 7 seconds: ganshizhong ganshizhong
函数
系统函数basename 和 dirname
1 2 3 4 5 basename [string/pathname] [suffix] [ec2-user@master test ]$ basename ./read.sh read.sh [ec2-user@master test ]$ basename ./read.sh .sh read
中括号都是可选参数
1 2 3 4 dirname 文件绝对路径 [ec2-user@master test ]$ dirname /home/ec2-user/test /read.sh /home/ec2-user/test
自定函数
1 2 3 4 5 6 [ function ] funname[()] { action; [return int;] } funname
1)必须在调用之前声明函数,shell是逐行运行的,不会先编译
2)函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #!/bin/bash function sum(){ s=0; s=$[$1 +$2 ] echo $s } read -p "input your parameter: " p1read -p "input your parameter: " p2sum $p1 $p2 [ec2-user@master test ]$ sh sumfunc.sh 1 2 3
shell工具(重点) cut 在文件中负责剪切数据。cut命令从文件的每一行剪切字节、字符和字段并输出。
基本用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 cut [选项参数] filename -f: 列号,提取第几列 -d: 分隔符,按照指定分隔符分割列 [ec2-user@master test ]$ cat cut.txt a b c d ee ff gg hh [ec2-user@master test ]$ cut -d " " -f 1,2 cut.txt a b c d ee ff gg [ec2-user@master test ]$ cat cut.txt |grep ff |cut -d " " -f 1 ee [ec2-user@master ~]$ echo $PATH /opt/java/jdk1.8.0_271/bin:/opt/hadoop/hadoop-3.2.3/bin:/opt/hadoop/hadoop-3.2.3/sbin:/usr/local /bin:/usr/bin:/usr/local /sbin:/usr/sbin:/opt/java/jdk1.8.0_271/bin:/home/ec2-user/.local /bin:/home/ec2-user/bin [ec2-user@master ~]$ echo $PATH | cut -d : -f 3- /opt/hadoop/hadoop-3.2.3/sbin:/usr/local /bin:/usr/bin:/usr/local /sbin:/usr/sbin:/opt/java/jdk1.8.0_271/bin:/home/ec2-user/.local /bin:/home/ec2-user/bin [ec2-user@master ~]$ ifconfig eth0 |grep "inet " inet 192.168.1.4 netmask 255.255.255.0 broadcast 192.168.1.255 [ec2-user@master ~]$ ifconfig eth0 |grep "inet " |cut -d "t" -f 2 192.168.1.4 ne [ec2-user@master ~]$ ifconfig eth0 |grep "inet " |cut -d "t" -f 2| cut -d" " -f2 192.168.1.4
缺点,cut只能切一个字符,如果存在很多空格,就会很麻烦
sed sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,成为”模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕中。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变 ,除非你使用重定向存储输出。
基本用法
1 2 3 4 5 6 7 sed [选项参数] "command" filename 选项参数: -e: 直接在指令列模式上进行sed的动作编辑 命令: a: 新增,a的后面可以接字串,在下一行出现 d: 删除 s:查找并替换
案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 [ec2-user@master ~]$ cat sed.txt gan shizhong g sz [ec2-user@master ~]$ sed "1a xiao ming" sed.txt gan shizhong xiao ming g sz [ec2-user@master ~]$ cat sed.txt gan shizhong g sz [ec2-user@master ~]$ sed "/sz/d" sed.txt gan shizhong [ec2-user@master ~]$ cat sed.txt gan shizhong g sz [ec2-user@master ~]$ sed "s/g sz/xiao ming/g" sed.txt gan shizhong xiao ming [ec2-user@master test ]$ sed -e "1d" -e "s/g sz/gan sz/g" sed.txt gan sz
awk 一个强大的文本分析工具,把文件逐行读取,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。
基本用法1 2 3 4 5 6 awk [选项参数] "pattern1{action1} pattern2{action2} ..." filename pattern: 表示AWK在数据中查找的内容,就是匹配模式 action: 在找到匹配内容时所执行的一系列命令,基本用print 选项参数 -F: 指定输入文件分析分隔符 -v: 复制一个用户定义变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 sudo cp /etc/passwd ./ sudo chown ec2-user:ec2-user passwd [ec2-user@master test ]$ awk -F : '/^root/{print $7}' passwd /bin/bash [ec2-user@master test ]$ awk -F : '/^root/{print $1,$7}' passwd root /bin/bash [ec2-user@master test ]$ awk -F : '/^root/{print $1 $7}' passwd root /bin/bash [ec2-user@master test ]$ awk -F : '/^root/{print $1","$7}' passwd root,/bin/bash [ec2-user@master test ]$ awk -F : 'BEGIN{print "user,shell"} {print $1","$7} END{print "gsz,/bin/gsz"}' passwd [ec2-user@master test ]$ awk -F : -v i=1 '{print $3+i}' passwd
此处要用单引号,单引号里的内容不可转义
两个斜杠之间时正则表达式
BEGIN 是所有行前,END是所有行后
awk 内置变量
1 2 3 FILENAME 文件名 NR 已读的记录数 NF 浏览记录的个数(切割后,列的个数)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [ec2-user@master test ]$ awk -F : '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF}' passwd filename:passwd,linenumber:1,columns:7 filename:passwd,linenumber:2,columns:7 filename:passwd,linenumber:3,columns:7 ... [ec2-user@master test ]$ ifconfig eth0 |grep "inet " |awk -F t '{print $2}' |awk -F " " '{print$1}' 192.168.1.4 [ec2-user@master test ]$ cat sed.txt gan shizhong g sz [ec2-user@master test ]$ awk '/^$/{print NR}' sed.txt 2
sort sort命令实在Linu非常有用,他将文件进行排序,并将排序结果标准输出
基本语法
1 2 3 4 5 sort (选项) (说明) -n: 依照数值大小排序 -r: 以相反的顺序来排序 -t: 设置排序时所用的分隔字符 -k: 指定排序的列
1 2 3 4 5 6 7 8 9 10 11 12 [ec2-user@master test ]$ cat sort.sh bb:40:5.1 bd:30:4.3 xz:50:2.3 cls:10:3.5 ss:25:1.6 [ec2-user@master test ]$ sort -t : -nrk 2 sort.sh xz:50:2.3 bb:40:5.1 bd:30:4.3 ss:25:1.6 cls:10:3.5
企业真实面试题(重点) 1 2 3 4 5 6 7 [ec2-user@master test ]$ cat chengji.txt 张三 40 李四 50 王五 60 [ec2-user@master test ]$ cat chengji.txt | awk -F " " '{sum+=$2} END{print sum}' 150
1 2 3 4 5 6 7 8 #!/bin/bash if [ -f file.txt ]then echo "存在" else echo "不存在" fi
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 [ec2-user@master test ]$ cat sort.txt 9 1 3 5 7 2 4 3 8 4 3 1 [ec2-user@master test ]$ sort -n sort.txt |awk '{a+=$0;print$0}END{print "SUM="a}' 1 1 2 3 3 3 4 4 5 7 8 9 SUM=50
awk里的变量可以添加可以不添加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [ec2-user@master test ]$ grep -r "sz" /home/ec2-user/test /home/ec2-user/test /sed.txt:g sz [ec2-user@master test ]$ grep -r "shizhong" /home/ec2-user/test /home/ec2-user/test /helloworld.sh:echo "hello world, ganshizhong" /home/ec2-user/test /if.sh: echo "ganshizhong is handsome" /home/ec2-user/test /if.sh: echo "ganshizhong" /home/ec2-user/test /sed.txt:gan shizhong [ec2-user@master test ]$ grep -r "shizhong" ./ ./helloworld.sh:echo "hello world, ganshizhong" ./if.sh: echo "ganshizhong is handsome" ./if.sh: echo "ganshizhong" ./sed.txt:gan shizhong [ec2-user@master test ]$ grep -r "shizhong" /home/ec2-user/test |cut -d ":" -f 1 /home/ec2-user/test /helloworld.sh /home/ec2-user/test /if.sh /home/ec2-user/test /if.sh /home/ec2-user/test /sed.txt
正则表达语法
字符
说明
\
转义
^
开始
$
结尾
*
0次或多次匹配
+
一次或多次匹配
shell编程题
Linux运维之批量下载指定网站的100个图片文件,并找出大于200KB的文件
1 2 3 4 5 6 #!/bin/bash for i in {1..100}do wget http://down.fengge.com/img/$i .png done find ./ -name "*.png" -size +200K
一个文本文件info.txt的内容如下: aa,201 zz,502 bb,1 ee,42 每行都是按照逗号分隔,其中第二列都是数字,请对该文件按照第二列数字从大到小排列。
1 sort -t "," -k 2 info.txt -rn
查看当前Linux服务器是否监听80端口,如果在监听,请找出其进程ID,并结束该进程。
1 2 3 4 lsof -i:端口号 kill -9 pidnetstat -tunlp
curl命令最常用的参数就是-I,仅返回头部信息,使用HEAD请求,获取的结果如下
1 curl -I http://192.168.100.115