Shell 脚本编程
1. 什么是 shell ?
Computers understand the language of zeros and ones known as binary language. In the early days of computing, instructions were provided using binary language, which is difficult for all of us to read and write. Therefore, in an operating system there is a special program called the shell. The shell accepts human readable commands and translates them into something the kernel can read and process.
shell 就是将人类可读的指令转换成计算机内核可能辨认并执行的程序。
常见的 shell 有:
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1595876670462&di=d756beb2122cf97c86c871e52d222d3d&imgtype=0&src=http%3A%2F%2Fc.hiphotos.baidu.com%2Fexp%2Fw%3D500%2Fsign%3Db1b881cb3dd12f2ece05ae607fc2d5ff%2F9d82d158ccbf6c814a5eccf4b73eb13533fa4045.jpg" align = "right" hspace="12"></img>
- Bourne Shell(sh)
- Bourne Again shell(bash)
- C Shell(csh)
- TENEX C Shell(tcsh)
- Korn shell(ksh)
- Z Shell(zsh)
- Friendly Interactive Shell(fish)
bash 是目前应用最多的 shell 。
<img src="https://book.apeland.cn/media/images/2019/05/09/uzbqic.png" align="right" height="200px" width="200px"></img>
shell 脚本 就是将实现一个工作的所有的命令依照执行的先后顺序,自上而下写入到一个文本文件中,而后给予执行权限。
比方:这是一个装置 ngixn 的脚本:
0 #!/bin/bash1 #install gcc2 yum -y install wget gcc pcre-devel zlib-devel3 #get nginx4 wget http://nginx.org/download/nginx-1.16.0.tar.gz56 tar xf nginx-1.16.0.tar.gz78 cd nginx-1.16.0910 ./configure --prefix=/usr/local/nginx11 make12 make install
给脚本赋予权限 chmod 700 ngnix_installation_script.sh
或者 sh nginx_installation_script.sh
, 就能够运行了.
2. shell 脚本根底
2.1 正文和命名
- shell 中应用
#
进行正文 - 脚本的第一行通常是指定解释器,即这个脚本必须通过什么解释器执行。这一行以
#!
字符结尾,这个字符称为 Shebang,所以这一行就叫做 Shebang 行。 - shell 脚本文件的命名和其余编程语言的命名相似,数字不能结尾,
2.2 运行一个脚本
脚本运行须要执行权限,当咱们给一个文件赋予执行权限后,该脚本就能够运行。
chmod u+x script_fileName
- 间接应用 bash 进行运行
bash script_fileName
2.3 shell 中的特殊符号,(会被非凡看待)
~
家目录!
执行历史命令,!!
示意执行上一条命令$
去变量符号&
后盾执行*
shell 中的通配符号, 匹配所有?
shell 中的通配符号, 匹配除回车外的一个字符;
多条命令之间的宰割符号|
管道符号\
本义符号- ` 反引号, 命令中执行命令
''
单引号, 脚本中字符串须要用单引号括起来,然而不会解释变量""
双引号, 用于包裹字符串
2.4 shell 中的重定向
>
重定向输出 笼罩原始的数据>>
从定向追加输出, 在原来的文件中追加数据<
重定向输入wc -l < /etc/passwd
统计数据流<<
重定向追加输入fdisk /dev/sdb <
格式化硬盘,从新缓存。
#!/bin/bashfdisk /dev/sdb << EOFnp3+534MwEOF
2.5 shell 中的数学运算
- expr 只能整数运算, 格局比拟古板 须要有空格
expr 1 + 1
- bc 应用 bc 计算器解决浮点运算,
scale=2
代表小数点保留两位echo "scale=2;3+100"|bc
- 双小圆括号进行运算 shell 中
(())
能够用来做数学运算echo $(( 100**3 ))
2.6 退出脚本
exit NUM 退出脚本, 开释系统资源 (NUM 代表一个整数) 代表脚本的返回值man exit 查看具体
3. 输入和输出
3.1 输入
3.1.1 echo
echo
命令的作用是在屏幕输入一行文本,能够将该命令的参数原样输入。
-n
: 在文本开端不增加换行符号-e
: 解释 引号中的特殊字符 (双引号和单引号)-b
: 删除一个符号倒计时脚本:
#!/bin/bashfor time in `seq 9 -1 0`;do echo -ne "\b$time" sleep 1done
3.2 输出
3.2.1 脚本的传参
$1
: 在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格局为:$n
。n
代表一个数字,,其中$0
为执行的文件名(蕴含文件门路),$1
为执行脚本的第一个参数,$2
为执行脚本的第二个参数,以此类推……$#
: 传递到脚本的参数个数$*
: 以一个单字符串显示所有向脚本传递的参数。 如$*
用「"」括起来的状况、以$1
$2
…$n
的模式输入所有参数。$$
: 脚本运行的以后过程 ID 号$!
: 后盾运行的最初一个过程的 ID 号$@
: 与$*
雷同,然而应用时加引号,并在引号中返回每个参数。 如"$@"
用「"」
括起来的状况、以"$1""$2" … "$n"
的模式输入所有参数。$-
: 显示 Shell 应用的以后选项,与 set 命令 性能雷同。$?
: 显示最初命令的退出状态。0 示意没有谬误,其余任何值表明有谬误。
3.2.2 Read
命令
默认承受键盘的输出,回车符代表输出完结
-p
: 打印信息-t
: 限定工夫-s
: 不回显-n
: 输出字符个数
#!/bin/bashclearecho -n -e "type something"read varecho "you typed:" $var
4. shell 变量
4.1 变量的操作
- 定义变量格局:
变量名 = 值
(不能有空号) - 应用
$
进行变量的读取 - 应用
unset 变量名
勾销变量
4.2 分类
- 本地变量:用户公有变量,只有 本用户能够应用,保留在家目录下的
.bash_profile
、.bashrc
文件中 - 全局变量:所有用户都能够应用,保留在
/etc/profile
、/etc/bashrc
文件中。应用export 变量名 = 变量值
进行全局变量的定义 - 用户自定义变量:用户自定义,比方脚本中的变量,终端敞开或者关机,都会失落,
6. shell 数组
6.1 根本数组
6.1.1 数组语法
- 定义:
数组名称 =(元素 1 元素 2 元素 3 ...)
- 数组的读出
${数组名称}[index]
6.1.2 数组的赋值
办法一: 一次赋一个值
array0[0]='tom'
办法二: 一次赋予多个值
array2=(tom jack alice)array3=(cat /etc/passwd) #心愿是将该文件中的每一个行作为一个元素赋值给数组 array3array4=(ls /var/ftp/Shell/for*)array5=(tom jack alice “bash shell”)
6.1.3 拜访数组元素
echo ${array1[0]} 拜访数组中的第一个元素echo ${array1[@]} 拜访数组中所有元素 等同于 echo ${array1[*]}echo ${#array1[@]} 统计数组元素的个数echo ${!array2[@]} 获取数组元素的索引echo ${array1[@]:1} 从数组下标 1 开始echo ${array1[@]:1:2} 从数组下标 1 开始,拜访两个元素
6.2 联结数组
关联数组能够容许用户自定义数组的索引,这样应用起来更加不便、高效。
须要先申明该数组为关联数组
#!/bin/bashdeclare -A a_arraya_array=([name]='suzl' [age]='25')echo ${a_array[name]}
拜访数组元素:
echo ${ass_array2[index2]} 拜访数组中的第二个元数echo ${ass_array2[@]} 拜访数组中所有元数 等同于 echo ${array1[*]}echo ${#ass_array2[@]} 取得数组元数的个数echo ${!ass_array2[@]} 取得数组元数的索引
7. 流程管制语句
7.0 shell 中的比拟运算
7.0.1 数学运算
运算符解释
-eq
等于-gt
大于-lt
小于-ge
大于或等于-le
小于或等于-ne
不等于
7.0.2 字符串比拟
运算符解释,留神字符串肯定别忘了应用引号引起来
==
等于!=
不等于-n
查看字符串长度是否大于 0-z
查看字符串长度是否为 0
7.0.3 文件的检查和比拟
-d
是否存在且为目录-e
查看文件是否存在-f
查看文件是否存在且为文件-s
查看文件是否存在且可读-w
查看文件是否存在且不为空-x
查看文件是否存在且可写-O
查看文件是否存在且可执行-G
查看文件是否存在并且被以后用户领有file1 -nt file2
查看 file1 是否比 file2 新file1 -ot file2
查看 file1 是否比 file2 旧
7.1 if 条件要加 []
7.1.1if
语法
if [condition] then commandsfi
7.1.2 if-else
if [condition] then commands1else commands2fi
7.1.3 if-else-elseif
if [condition 1] then commands1elif [condition 2] then commands2 .......else commandsXfi
7.1.4 if
的高级用法
- ????条件符号应用双圆括号
(())
,能够在条件中植入数学表达式 - ????应用单方括号
[[]]
, 能够在条件中 应用通配符
#!/bin/bashif ((100*3+10>500 ));then echo ">"else echo "<"fi
for str in java javascript js do if [["$str" == j*]];then echo "$str" fi done
7.2 for
7.2.1 for 语法
语法 1: 无限变量
for var in v1 v2 v3.. do commanddone
语法 2: C 语言写法
for ((变量; 条件; 变动)) do commanddone
语法 3: 有限循环
for ((;;)) do commanddone
7.2.1 循环管制
continue
跳过循环中的某次循环continue
跳过循环中的某次循环break
跳出循环继续执行后续代码, 能够应用break N
循环退出, 循环从里往外排序为1 - N
#!/bin/bashfor ((i=9;i>0;i--))do if [$i -eq 5] then continue else echo -n -e "\b$i===" sleep 1 fidoneecho -e
#!/bin/bashfor ((i=1;i<100;i++))do echo "ha" for((;;)) do echo "the inner loop" break 2 donedone打印:hathe inner loop
7.3 while
7.3.1 语法格局: 条件能够是 5 种运算中的任意一种
数学, 字符串比拟, 文件类型, 逻辑运算, 赋值运算
while [condition]do commanddone
7.4 until
while
是条件为真开始时循环, until
是条件为假开始循环.
7.5 case (多条件执行语句)
语法 (比拟奇怪):
case var incondition1) command1;;condition1) command2;;...esac
留神 3.2.1 中非凡的变量
8. shell 函数
8.1 函数语法
# 形式 1func_name (){ command return N}# 形式 2function func_name{ command return N}
8.2 调用函数
间接应用函数名字, 不加括号: func_name
9. 正则表达式
9.1 特殊字符
9.1.1 定位字符: 锚定字符
^
锚定结尾^a
以 a 结尾, 默认锚定一个字符$
锚定结尾a$
以 a 结尾, 默认锚定一个字符^$
两个字符在一起示意精准匹配grep
默认不反对正则表达式, 须要加上-e
参数, 或者应用egrep
其余特定符号的意思
9.1.2 匹配符: 匹配字符串
.
除了回车符号任意的字符(|)
字符串分组^(a|b)c$
a 或者 b 结尾以 c 结尾的串[]
定义字符类, 匹配括号中的一个字符[^]
示意否定括号中呈现字符类中的字符, 取反\
转义字符|
或符号
9.1.3 限定符号 : 对后面的字符或者字符串做限定阐明
*
某个字符之后加星号示意该字符不呈现或呈现屡次 (0 次或者屡次 )?
与星号类似,但略有变动,示意该字符呈现一次或不呈现 (0 次或者 1 次)+
与星号类似,示意其后面字符呈现 一次或屡次 , 但必须呈现一次{n,m}
某个字符之后呈现,示意该字符 起码n
次, 最多m
次{m}
正好呈现了m
次
9.1.4 POSIX 特殊字符
[:alnum:]
匹配任意字母字符 0-9 a-z A-Z[:alpha:]
匹配任意字母,大写或小写[:digit:]
数字 0-9[:graph:]
非空字符 ( 非空格控制字符)[:lower:]
小写字符 a-z[:upper:]
大写字符 A-Z[:cntrl:]
控制字符[:print:]
非空字符 ( 包含空格)[:punct:]
标点符号[:blank:]
空格和 TAB 字符[:xdigit:]
16 进制数字[:space:]
所有空白字符 ( 新行、空格、制表符)
10. shell 文件操作
非交互式文件操作, vim 和 nano 是交互式文件操作.
10.1 sed (stream editor)
- CoolShell 的 sed 扼要教程
10.2 awk(pattern-directed scanning and processing language)
- CoolShell 的 AWK 扼要教程
参考链接
- 鸟哥的 Linux 私房菜
- 路飞学城 shell 教程
- The Linux Command Line