Shell脚本
Shell:命令行解释器,接收应用程序/用户命令,然后调用操作系统内核。
1.入门
脚本以#!/bin/bash开头
1 xqchang@sam-System-Product-Name:~/linux/datas$ touch helloworld.sh 2 xqchang@sam-System-Product-Name:~/linux/datas$ vim helloworld.sh 3 4 ------按i进入insert模式 5 #!/bin/bash 6 echo "helloworld" 7 ------输入完毕后按esc退出insert,:wq 8 9 xqchang@sam-System-Product-Name:~/linux/datas$ bash helloworld.sh -----执行方式一 10 helloworld 11 xqchang@sam-System-Product-Name:~/linux/datas$ chmod 777 helloworld.sh 12 xqchang@sam-System-Product-Name:~/linux/datas$ ./helloworld.sh ----执行方式二,需要执行权限 13 helloworld
多命令处理
在linux/datas/目录下,创建一个banzhang.txt并在文件中写入"I IOVE YOU"字符
1 xqchang@sam-System-Product-Name:~/linux/datas$ touch batch.sh 2 xqchang@sam-System-Product-Name:~/linux/datas$ vim batch.sh 3 4 ----------- 5 #!/bin/bash 6 cd /home/xqchang/linux/datas/ 7 touch banzhang.txt 8 echo "I LOVE YOU" >> banzhang.txt 9 ----------- 10 11 xqchang@sam-System-Product-Name:~/linux/datas$ bash batch.sh
12 xqchang@sam-System-Product-Name:~/linux/datas$ cat banzhang.txt
13 I LOVE YOU
2.变量
系统变量
1 xqchang@sam-System-Product-Name:~/linux/datas$ echo $HOME 2 /home/xqchang 3 xqchang@sam-System-Product-Name:~/linux/datas$ echo $PWD 4 /home/xqchang/linux/datas 5 xqchang@sam-System-Product-Name:~/linux/datas$ echo $SHELL 6 /bin/bash 7 xqchang@sam-System-Product-Name:~/linux/datas$ echo $USER 8 xqchang
自定义变量
1)基本语法
- 定义变量:变量=值 注意:等号两边不能留有空格!
- 撤销变量:unset 变量
- 输出变量:echo $变量
- 声明静态变量: readonly 变量,注意:不能unset
1 ---定义变量 2 3 xqchang@sam-System-Product-Name:~/linux/datas$ A=1 4 xqchang@sam-System-Product-Name:~/linux/datas$ echo $A 5 1 6 xqchang@sam-System-Product-Name:~/linux/datas$ unset A 7 xqchang@sam-System-Product-Name:~/linux/datas$ echo $A 8 9 ---静态变量 10 xqchang@sam-System-Product-Name:~/linux/datas$ readonly B=2 11 xqchang@sam-System-Product-Name:~/linux/datas$ echo $B 12 2 13 xqchang@sam-System-Product-Name:~/linux/datas$ unset B 14 -bash: unset: B: cannot unset: readonly variable
2)变量定义规则
- 变量名称可以由字母,数字和下划线组成,不能以数字开头,环境变量名建议大写;
- 等号两侧不能有空格;
- 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算;
- 变量的值如果有空格,需要使用双引号或单引号括起来;
- 可把变量提升为全局变量,供其他shell程序使用【export 变量】
3)特殊变量
- $n (描述:n为数字,$0代表脚本名称,10以内参数用$1-9 表 示 , 10 以上的需要用大括号包含,如${10})
1 xqchang@sam-System-Product-Name:~/linux/datas$ touch parameter.sh 2 xqchang@sam-System-Product-Name:~/linux/datas$ vim parameter.sh 3 4 ------打印前3个变量 5 #!/bin/bash 6 echo "$0 $1 $2 $3" 7 ------ 8 9 xqchang@sam-System-Product-Name:~/linux/datas$ bash parameter.sh 10 parameter.sh 11 xqchang@sam-System-Product-Name:~/linux/datas$ bash parameter.sh x 12 parameter.sh x 13 xqchang@sam-System-Product-Name:~/linux/datas$ bash parameter.sh x y z p 14 parameter.sh x y z
- $# (描述:获取所有输入参数个数,常用于循环)
- $* (描述:代表命令行中所有的参数,把所有参数看成一个整体)
- $@ (描述:也代表命令行中所有的参数,不过把每个参数区分对待)
- $? (描述:最后一次执行命令的状态,0:正确执行,非0则错误执行)
1 xqchang@sam-System-Product-Name:~/linux/datas$ bash helloworld.sh 2 helloworld 3 xqchang@sam-System-Product-Name:~/linux/datas$ echo $? 4 0
3.运算符
语法
- $((运算式)) 或 $[运算式]
- expr +,-,\*,/,% 加减乘除取余,expr运算符间要有空格
1 xqchang@sam-System-Product-Name:~/linux/datas$ expr 3 - 1 2 2 3 4 ---- 计算(2+3)*4 5 xqchang@sam-System-Product-Name:~/linux/datas$ expr `expr 2 + 3` \* 4 6 20 7 xqchang@sam-System-Product-Name:~/linux/datas$ s=$[(2+3)*4] 8 xqchang@sam-System-Product-Name:~/linux/datas$ echo $s 9 20
4.条件判断
[ condition ] (注意:condition前后要有空格,非空即为true)
(4)多条件判断,&& ||
1 ----判断23是否大于2 2 xqchang@sam-System-Product-Name:~/linux/datas$ [ 23 -ge 22 ] 3 xqchang@sam-System-Product-Name:~/linux/datas$ echo $? 4 0 5 ----判断helloworld.sh是否有写入权限 6 xqchang@sam-System-Product-Name:~/linux/datas$ [ -w helloworld.sh ] 7 xqchang@sam-System-Product-Name:~/linux/datas$ echo $? 8 0 9 ----判断目录中文件是否存在 10 xqchang@sam-System-Product-Name:~/linux/datas$ [ -e /home/xqchang/linux/datas ] 11 xqchang@sam-System-Product-Name:~/linux/datas$ echo $? 12 0 13 14 xqchang@sam-System-Product-Name:~/linux/datas$ [ condition ] && echo OK || echo no 15 OK 16 xqchang@sam-System-Product-Name:~/linux/datas$ [ condition ] && [ ] || echo no 17 no
5.流程控制
if判断
注意:[ 条件判断式 ],条件判断式前后要有空格,if后要有空格;
1 #!/bin/bash 2 if [ $1 -eq 1 ] 3 then 4 echo "第一个参数为1" 5 elif [ $1 -eq 2 ] 6 then 7 echo "第一个参数为2" 8 fi
case语句
输入的第一个参数为1输出“班长”,为2输出“团支书”,其他输出“普通学生”
1 #!/bin/bash 2 case $1 in 3 1) 4 echo "班长" 5 ;; 6 2) 7 echo "团支书" 8 ;; 9 *) 10 echo "普通学生" 11 ;; 12 esac
for循环
形式1
1 ----计算1到100的和 2 #!/bin/bash 3 4 s=0 5 for((i=1;i<=100;i++)) 6 do 7 s=$[$s+$i] 8 done 9 10 echo $s
形式2
1 xqchang@sam-System-Product-Name:~/linux/datas$ touch for2.sh 2 xqchang@sam-System-Product-Name:~/linux/datas$ vim for2.sh 3 ----第一个for循环等同于$@,等同于"$@" 4 #!/bin/bash 5 6 for i in $* 7 do 8 echo $i 9 done 10 11 for j in "$*" 12 do 13 echo $j 14 done 15 ---- 16 xqchang@sam-System-Product-Name:~/linux/datas$ bash for2.sh 1 2 3 17 1 18 2 19 3 20 1 2 3
while循环
1 ----计算1到100的和 2 #!/bin/bash 3 4 s=0 5 i=1 6 while [ $i -le 100 ] 7 do 8 s=$[$s + $i] 9 i=$[$i + 1] 10 done 11 echo $s
6.read读取控制台输入
read(选项)(参数)
选项:
- -p:指定读取值时的提示符;
- -t:指定读取值时等待的时间(秒);
参数:
- 变量:指定读取值的变量名;
1 xqchang@sam-System-Product-Name:~/linux/datas$ touch read.sh 2 xqchang@sam-System-Product-Name:~/linux/datas$ vim read.sh 3 ---- 4 #!/bin/bash 5 read -t 7 -p "7秒内输入你的名字" NAME 6 echo $NAME 7 ---- 8 xqchang@sam-System-Product-Name:~/linux/datas$ bash read.sh 9 7秒内输入你的名字cxq 10 cxq
7.函数
系统函数
basename [string / pathname] [suffix] (描述:basename命令会删掉所有的前缀包括最后一个‘/’字符,然后将字符串显示出来)
suffix为后缀,如果suffix被指定,basename会将pathname或string中的suffix去掉;
1 xqchang@sam-System-Product-Name:~/linux/datas$ basename /home/xqchang/linux/datas/banzhang.txt 2 banzhang.txt 3 xqchang@sam-System-Product-Name:~/linux/datas$ basename /home/xqchang/linux/datas/banzhang.txt .txt 4 banzhang
dirname 文件绝对路径 (描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分))
1 xqchang@sam-System-Product-Name:~/linux/datas$ dirname /home/xqchang/linux/datas/banzhang.txt 2 /home/xqchang/linux/datas
自定义函数
1 # 格式 2 [ function ] funname[()] 3 { 4 Action: 5 [return int;] 6 } 7 funname
Tip:
- 先申明函数,再调用函数(shell逐行运行)
- 函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。
1 #!/bin/bash 2 function sum() 3 { 4 s=0; 5 s=$[$1 + $2] 6 echo $s 7 } 8 read -p "input your param1:" P1 9 read -p "input your param2:" P2 10 sum $P1 $P2
8.shell工具
cut
cut命令从文件的每一行剪切字节,字符和字段并将这些字节,字符和字段输出;
cut [选项参数] filename
- -f 列号,提取第几列
- -d 分隔符,按照指定分隔符分隔列
案例1:
1 xqchang@sam-System-Product-Name:~/linux/datas$ touch cut.txt 2 xqchang@sam-System-Product-Name:~/linux/datas$ vim cut.txt 3 dong shen 4 guan zhen 5 wo wo 6 lai lai 7 le le 8 9 ----切割第一列 10 xqchang@sam-System-Product-Name:~/linux/datas$ cut -d " " -f 1 cut.txt 11 dong 12 guan 13 wo 14 lai 15 le 16 ----切割第二三列 17 xqchang@sam-System-Product-Name:~/linux/datas$ cut -d " " -f 2,3 cut.txt 18 shen 19 zhen 20 wo 21 lai 22 le 23 ----从cut.txt文件中切割出guan 24 xqchang@sam-System-Product-Name:~/linux/datas$ cat cut.txt | grep guan 25 guan zhen 26 xqchang@sam-System-Product-Name:~/linux/datas$ cat cut.txt | grep guan | cut -d " " -f 1 27 guan
案例2:
1 ----选取系统PATH变量值,第2个“:”开始后的所有路径 2 xqchang@sam-System-Product-Name:~/linux/datas$ echo $PATH 3 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/ga mes:/snap/bin 4 xqchang@sam-System-Product-Name:~/linux/datas$ echo $PATH | cut -d ":" -f 3- 5 /usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
sed
sed是一种流编辑器,它一次处理一行内容,处理时,把当前处理的行存储在临时缓冲区中,成为“模式空间”,接着sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕,接着处理下一行,这样不断重复,知道文件末尾,文件内容并没有改变,除非你使用重定向存储输出。
sed [选项参数] ‘command’ filename
- -e 直接在指令列模式上进行sed的动作编辑
命令功能描述
- a 新增
- d 删除
- s 查找并替换
1 xqchang@sam-System-Product-Name:~/linux/datas$ touch seq.txt 2 xqchang@sam-System-Product-Name:~/linux/datas$ vim sed.txt 3 dong shen 4 guan zhen 5 wo wo 6 lai lai 7 le le 8 9 ----将“feng jing”这个单词插入到sed.txt的第二行下(并没有改变原文件) 10 xqchang@sam-System-Product-Name:~/linux/datas$ sed "2a feng jing" sed.txt 11 dong shen 12 guan zhen 13 feng jing 14 wo wo 15 lai lai 16 le le 17 18 ----删除sed.txt文件中包含wo的行 19 xqchang@sam-System-Product-Name:~/linux/datas$ sed "/wo/d" sed.txt 20 dong shen 21 guan zhen 22 lai lai 23 le le 24 25 ----将sed.txt文件中wo替换成ni 26 xqchang@sam-System-Product-Name:~/linux/datas$ sed "s/wo/ni/g" sed.txt 27 dong shen 28 guan zhen 29 ni ni 30 lai lai 31 le le 32 33 ----将sed.txt文件中的第二行删除并将wo替换成ni 34 xqchang@sam-System-Product-Name:~/linux/datas$ sed -e "2d" -e "s/wo/ni/g" sed.txt 35 dong shen 36 ni ni 37 lai lai 38 le le
awk
awk 一个强大文件分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理;
awk [选项参数] 'pattern1 {action1} pattern2{action2}..' filename
选项参数
- -F 指定输入文件分隔符
- -v 赋值一个用户定义变量
pattern:表示awk在数据中查找的内容,就是匹配模式;
action:在找到匹配内容时所执行的一系列命令;
【两个斜杠之间是正则表达式】
sort
将文件进行排序,并将排序结果标准输出。
sort(选项)(参数)
选项:
- -n 依照数值的大小排序
- -r 以相反的顺序来排序
- -t 设置排序时所用的分隔字符
- -k 指定需要排序的列
参数:指定待排序的文件列表
1 xqchang@sam-System-Product-Name:~/linux/datas$ touch sort.sh 2 xqchang@sam-System-Product-Name:~/linux/datas$ vim sort.sh 3 bb:40:5.4 4 bd:20:4.2 5 xz:50:2.3 6 cls:10:3.5 7 ss:30:1.6 8 xqchang@sam-System-Product-Name:~/linux/datas$ sort -t : -nrk 3 sort.sh 9 bb:40:5.4 10 bd:20:4.2 11 cls:10:3.5 12 xz:50:2.3 13 ss:30:1.6