编程工具(三)Shell编程基础
2018-01-09 22:09
260 查看
参考:《Shell从入门到精通》
参考:Shell 编程快速入门
参考:Shell 教程
参考:Shell编程入门总结(一)
Shell的用处:
shell简单、灵活、高效,特别适合处理一些系统管理方面的小问题
shell可以实现自动化管理,让系统管理员的工作变得容易、简单、高效
shell脚本可移植性好,在unix/linux系统中可灵活移植,几乎不用任何设置就能正常运行
shell脚本可轻松方便读取和修改源代码,不需要编译
Shell不适用的场合:
资源密集型的任务,尤其在需要考虑效率时(比如排序,hash 等)
需要处理大任务的数学操作,尤其是浮点运算,精确运算,或者复杂的算术运算(这种情况一般使用C++或FORTRAN 来处理)
有跨平台移植需求(一般使用C 或Java)
复杂的应用,在必须使用结构化编程的时候(需要变量的类型检查,函数原型,等等)
对于影响系统全局性的关键任务应用。
对于安全有很高要求的任务,比如你需要一个健壮的系统来防止入侵,破解,恶意破坏等等.
需要直接操作系统硬件、需要产生或操作图形化界面 GUI
私人的,闭源的应用(shell 脚本把代码就放在文本文件中,全世界都能看到)
Linux
Linux默认安装就带了shell解释器。
Mac OS
Mac OS不仅带了sh、bash这两个最基础的解释器,还内置了ksh、csh、zsh等不常用的解释器。
Windows上的模拟器
windows出厂时没有内置shell解释器,需要自行安装,为了同时能用grep, awk, curl等工具,最好装一个cygwin或者mingw来模拟linux环境。
sh
即Bourne shell,POSIX(Portable Operating System Interface)标准的shell解释器,它的二进制文件路径通常是/bin/sh,由Bell Labs开发。
bash
Bash是Bourne shell的替代品,属GNU Project,二进制文件路径通常是/bin/bash。在CentOS里,/bin/sh是一个指向/bin/bash的符号链接,但在Mac OS上不是,/bin/sh和/bin/bash是两个不同的文件,尽管它们的大小只相差100字节左右,业界通常混用bash、sh、和shell。
通常shell脚本以.sh为后缀。在编写shell时,第一行一定要指明系统需要哪种shell解释用户的shell程序,如:
#!/bin/sh
#!/bin/bash
#!/bin/csh
#!/bin/tcsh
#!/bin/ksh
Shell的执行
通常,shell脚本会以#!/bin/sh作为默认的shell程序。执行shell的方式有两种:
第一种是为shell脚本加上可执行权限并执行;
第二种是通过sh命令执行shell脚本,例如执行当前目录下的run.sh脚本,命令如下:
1. 美元符号
美元符号表示变量替换,即用其后面指定的变量的值来代替变量。反斜线“\”为转义字符,转义字符告诉shell不要对其后面的那个字符进行特殊处理,只是当做普通字符。而shell下的引号情况比较复杂,分为三种:双引号("),单引号(')和倒引号(`)。他们的作用都不尽相同,以下一一说明。
2. 双引号(")
由双引号括起来的字符,除$,倒引号(`)和反斜线(\)仍保留其特殊功能外,其余字符均作为普通字符对待。
3. 单引号(')
由单引号括起来的字符都作为普通字符出现。
4. 倒引号(`)
由倒引号括起来的字符串被shell解释为命令行,在执行时,shell会先执行该命令,并以它的标准输出结果取代整个引号部分。
示例1的代码及输出如下:
【双引号中的倒引号和美元符号保持原来的功能】
【双引号中的转义字符保持原来的功能】
6. 变量类型
运行shell时,会同时存在三种变量:
1) 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
2) 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
3) shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
7. 变量的通配符
假设有变量 var=http://www.aaa.com/123.htm
1. # 号截取,从左边开始删除第一个匹配到的字符及左边的字符,保留右边字符。
# 号是运算符,*// 表示 // 号及左边的所有字符,即删除 http://
结果是 :www.aaa.com/123.htm
2. ## 号截取,从左边开始删除最后一个匹配到的字符及左边的字符,保留右边字符。
##*/ 表示从左边开始删除最后(最右边)一个 / 号及左边的所有字符,即删除 http://www.aaa.com/
结果是 123.htm
3. %号截取,删除从右开始第一个匹配到的字符及右边字符,保留左边字符
%/* 表示从右边开始,删除第一个 / 号及右边的字符
结果是:http://www.aaa.com
4. %% 号截取,删除从右开始最后一个匹配到的字符及右边字符,保留左边字符
%%/* 表示从右边开始,删除最后(最左边)一个 / 号及右边的字符
结果是:http:
5. :从左边第几个字符开始,及字符的个数
其中的 0 表示左边第一个字符开始,5 表示字符的总个数。
结果是:http:
6. 从左边第几个字符开始,一直到结束。
其中的 7 表示左边第8个字符开始,一直到结束。
结果是 :www.aaa.com/123.htm
7. 从右边第几个字符开始,及字符的个数
其中的 0-7 表示右边算起第七个字符开始,3 表示字符的个数。
结果是:123
8. 从右边第几个字符开始,一直到结束。
表示从右边第七个字符开始,一直到结束。
结果是:123.htm
注:(左边的第一个字符是用 0 表示,右边的第一个字符用 0-1 表示)
1. 定义数组
3. 获取数组的长度
其中name为函数名,commands为一系列包含在函数中的命令,函数中须至少包含一条命令,return为可选。Shell 提供了一个参数$?可用来检查退出状态,即函数中的返回值(返回值只能是整数)。
我们可以在执行 Shell 脚本或函数时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推。$0 为执行的文件名(在bash中为“bash”)。
条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的,必须写成 [ $a == $b ]。
持数字,不支持字符串,除非字符串的值是数字。下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
2. for语句
3. while语句
while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:
4. util语句
until循环执行一系列命令直至条件为真时停止。until循环与while循环在处理方式上刚好相反。一般while循环优于until循环,但在某些时候—也只是极少数情况下,until循环更加有用。until 语法格式:
5. case
Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。case语句格式如下:
test expression
或
[ expression ]
其中expression 为一个表达式,其执行结果是 true 或者是 false。当表达式为真时,这个 test 命令返回一个0退出状态,当表达式为假时,test 命令退出状态为1。
-a array:把输入赋值到数组 array 中,从索引号零开始
-d delimiter:用字符串 delimiter 中的第一个字符指示输入结束,而不是一个换行符
-e:使用 Readline 来处理输入。这使得与命令行相同的方式编辑输入
-n num:读取 num 个输入字符,而不是整行
-p prompt:为输入显示提示信息,使用字符串 prompt
-r:Raw mode. 不把反斜杠字符解释为转义字符
-s:Silent mode. 不会在屏幕上显示输入的字符。当输入密码和其它确认信息的时候,这会很有帮助
-t seconds:超时. 几秒钟后终止输入。read 会返回一个非零退出状态,若输入超时
-u fd:使用文件描述符 fd 中的输入,而不是标准输入
密码输入脚本
此脚本提示用户输入一个密码,若在10秒内没有完成输入,则脚本会退出并返回一个错误。因包含了一个 -s 选项,所以输入的密码不会出现在屏幕上。
通过对输入的数据进行校验,得到期望范围内的输入
一种常见的交互类型称为菜单驱动,从逻辑上讲,这个脚本被分为两部分。第一部分显示菜单和用户输入。第二部分确认用户反馈,并执行 选择的行动
标准输入 standard input 0
正确输出 standard output 1
错误输出 error output 2
这些默认的输出,输入都是linux系统内定的,我们在使用过程中,有时候并不希望执行结果输出到屏幕。我想输出到文件或其它设备。这个时候我们就需要进行输出重定向了。
输出重定向的命令如下所示:
1、shell遇到”>”操作符,会判断右边文件是否存在,如果存在就先删除,并且创建新文件。不存在直接创建。 无论左边命令执行是否成功。右边文件都会变为空。
2、“>>”操作符,判断右边文件,如果不存在,先创建。以添加方式打开文件,会分配一个文件描述符[不特别指定,默认为1,2]然后,与左边的标准输出(1)或错误输出(2) 绑定。
3、当命令:执行完,绑定文件的描述符也自动失效。0,1,2又会空闲。
4、一条命令启动,命令的输入,正确输出,错误输出,默认分别绑定0,1,2文件描述符。
5、一条命令在执行前,先会检查输出是否正确,如果输出设备错误,将不会进行命令执行
2. /dev/null 空设备文件,相当于垃圾桶
3. >前面的数字:
0代表标准输入
1代表stdout标准输出,默认值为1,所以”1>/dev/null”可以简写为”>/dev/null”
2代表stderr标准错误输出
4. 2>&1代表把stderr标准错误输出 重定向 到stdout标准输出
所以,1>/dev/null 2>&1的解释就是:
将stdout标准输出重定向到空设备文件/dev/null ,同时将stderr标准错误输出的重定向跟stdout标准输出重定向一致,也输出到空设备文件/dev/null。
参考:Shell 编程快速入门
参考:Shell 教程
参考:Shell编程入门总结(一)
一、Shell
Shell脚本(英语:Shell script)是一种电脑程序与文本文件,内容由一连串的shell命令组成,由Unix shell扮演命令行解释器的角色,经由Unix Shell直译其内容后运作。Shell的用处:
shell简单、灵活、高效,特别适合处理一些系统管理方面的小问题
shell可以实现自动化管理,让系统管理员的工作变得容易、简单、高效
shell脚本可移植性好,在unix/linux系统中可灵活移植,几乎不用任何设置就能正常运行
shell脚本可轻松方便读取和修改源代码,不需要编译
Shell不适用的场合:
资源密集型的任务,尤其在需要考虑效率时(比如排序,hash 等)
需要处理大任务的数学操作,尤其是浮点运算,精确运算,或者复杂的算术运算(这种情况一般使用C++或FORTRAN 来处理)
有跨平台移植需求(一般使用C 或Java)
复杂的应用,在必须使用结构化编程的时候(需要变量的类型检查,函数原型,等等)
对于影响系统全局性的关键任务应用。
对于安全有很高要求的任务,比如你需要一个健壮的系统来防止入侵,破解,恶意破坏等等.
需要直接操作系统硬件、需要产生或操作图形化界面 GUI
私人的,闭源的应用(shell 脚本把代码就放在文本文件中,全世界都能看到)
二、Shell环境
shell编程跟java、php编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。当前主流的操作系统都支持shell编程。Linux
Linux默认安装就带了shell解释器。
Mac OS
Mac OS不仅带了sh、bash这两个最基础的解释器,还内置了ksh、csh、zsh等不常用的解释器。
Windows上的模拟器
windows出厂时没有内置shell解释器,需要自行安装,为了同时能用grep, awk, curl等工具,最好装一个cygwin或者mingw来模拟linux环境。
sh
即Bourne shell,POSIX(Portable Operating System Interface)标准的shell解释器,它的二进制文件路径通常是/bin/sh,由Bell Labs开发。
bash
Bash是Bourne shell的替代品,属GNU Project,二进制文件路径通常是/bin/bash。在CentOS里,/bin/sh是一个指向/bin/bash的符号链接,但在Mac OS上不是,/bin/sh和/bin/bash是两个不同的文件,尽管它们的大小只相差100字节左右,业界通常混用bash、sh、和shell。
三、Shell的解释和执行
Shell的格式通常shell脚本以.sh为后缀。在编写shell时,第一行一定要指明系统需要哪种shell解释用户的shell程序,如:
#!/bin/sh
#!/bin/bash
#!/bin/csh
#!/bin/tcsh
#!/bin/ksh
Shell的执行
通常,shell脚本会以#!/bin/sh作为默认的shell程序。执行shell的方式有两种:
第一种是为shell脚本加上可执行权限并执行;
第二种是通过sh命令执行shell脚本,例如执行当前目录下的run.sh脚本,命令如下:
//为shell脚本直接加上可执行权限并执行 chmod 755 run.sh ./run.sh //通过sh命令执行shell脚本 sh run.sh
四、Shell中的特殊字符
和其他编程语言一样,shell里也有特殊字符。常见的有美元符号($),反斜线(\)和引号。1. 美元符号
美元符号表示变量替换,即用其后面指定的变量的值来代替变量。反斜线“\”为转义字符,转义字符告诉shell不要对其后面的那个字符进行特殊处理,只是当做普通字符。而shell下的引号情况比较复杂,分为三种:双引号("),单引号(')和倒引号(`)。他们的作用都不尽相同,以下一一说明。
2. 双引号(")
由双引号括起来的字符,除$,倒引号(`)和反斜线(\)仍保留其特殊功能外,其余字符均作为普通字符对待。
3. 单引号(')
由单引号括起来的字符都作为普通字符出现。
4. 倒引号(`)
由倒引号括起来的字符串被shell解释为命令行,在执行时,shell会先执行该命令,并以它的标准输出结果取代整个引号部分。
示例1的代码及输出如下:
#echo "My current directory is `pwd` and logname is $LOGNAME"
【双引号中的倒引号和美元符号保持原来的功能】
My current directory is /root and logname is root示例2的代码及输出如下:
#echo "My current directory is `pwd` and logname is \$LOGNAME"
【双引号中的转义字符保持原来的功能】
My current directory is /root and logname is $LOGNAME示例3的代码及输出如下:
#echo 'My current directory is `pwd` and logname is $LOGNAME'【单引号里面的内容不变】
My current directory is `pwd`and logname is $LOGNAME
五、Shell中的变量
1. 创建变量或给变量赋值variable=value(注:等号左右不能有空格)2. 可以在同一行中对多个变量赋值
a=5 b="a string"3. 使用变量
$variable 或 ${variable}4. 只读变量
myUrl="http://www.w3cschool.cc" readonly myUrl myUrl="http://www.baidu.com"运行脚本,结果如下:
/bin/sh: NAME: This variable is read only.5. 删除变量
unset variable_name变量被删除后不能再次使用。unset 命令不能删除只读变量。
6. 变量类型
运行shell时,会同时存在三种变量:
1) 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
2) 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
3) shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
7. 变量的通配符
假设有变量 var=http://www.aaa.com/123.htm
1. # 号截取,从左边开始删除第一个匹配到的字符及左边的字符,保留右边字符。
echo ${var#*//}
# 号是运算符,*// 表示 // 号及左边的所有字符,即删除 http://
结果是 :www.aaa.com/123.htm
2. ## 号截取,从左边开始删除最后一个匹配到的字符及左边的字符,保留右边字符。
echo ${var##*/}
##*/ 表示从左边开始删除最后(最右边)一个 / 号及左边的所有字符,即删除 http://www.aaa.com/
结果是 123.htm
3. %号截取,删除从右开始第一个匹配到的字符及右边字符,保留左边字符
echo ${var%/*}
%/* 表示从右边开始,删除第一个 / 号及右边的字符
结果是:http://www.aaa.com
4. %% 号截取,删除从右开始最后一个匹配到的字符及右边字符,保留左边字符
echo ${var%%/*}
%%/* 表示从右边开始,删除最后(最左边)一个 / 号及右边的字符
结果是:http:
5. :从左边第几个字符开始,及字符的个数
echo ${var:0:5}
其中的 0 表示左边第一个字符开始,5 表示字符的总个数。
结果是:http:
6. 从左边第几个字符开始,一直到结束。
echo ${var:7}
其中的 7 表示左边第8个字符开始,一直到结束。
结果是 :www.aaa.com/123.htm
7. 从右边第几个字符开始,及字符的个数
echo ${var:0-7:3}
其中的 0-7 表示右边算起第七个字符开始,3 表示字符的个数。
结果是:123
8. 从右边第几个字符开始,一直到结束。
echo ${var:0-7}
表示从右边第七个字符开始,一直到结束。
结果是:123.htm
注:(左边的第一个字符是用 0 表示,右边的第一个字符用 0-1 表示)
六、Shell中的数组
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。类似与C语言,数组元素的下标由0开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0。1. 定义数组
array_name=(value0 value1 value2 value3)用括号来表示数组,数组元素用"空格"符号分割开。还可以单独定义数组的各个分量:
array_name[0]=value0 array_name[1]=value1 array_name =valuen2. 读取数组
valuen=${array_name }使用@符号可以获取数组中的所有元素
3. 获取数组的长度
# 取得数组元素的个数 length=${#array_name[@]} # 或者 length=${#array_name[*]} # 取得数组单个元素的长度 lengthn=${#array_name }
七、Shell中的函数和运算符
7.1 函数语法形式
function name { commands return }或
name () { commands return }
其中name为函数名,commands为一系列包含在函数中的命令,函数中须至少包含一条命令,return为可选。Shell 提供了一个参数$?可用来检查退出状态,即函数中的返回值(返回值只能是整数)。
我们可以在执行 Shell 脚本或函数时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推。$0 为执行的文件名(在bash中为“bash”)。
参数处理 | 说明 |
---|---|
$# | 传递到脚本或函数的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数。 如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数。 如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。 |
$- | 显示Shell使用的当前选项,与set命令功能相同。 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
7.2 表达式计算工具
expr 是一款表达式计算工具,使用它能完成表达式的求值操作。如下两个数相加(注意使用的是反引号 ` 而不是单引号 '):#!/bin/bash val=`expr 2 + 2` echo "两数之和为 : $val"表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。
7.3 算数运算符
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | `expr $a + $b` 结果为 30。 |
- | 减法 | `expr $a - $b` 结果为 -10。 |
* | 乘法 | `expr $a \* $b` 结果为 200。 |
/ | 除法 | `expr $b / $a` 结果为 2。 |
% | 取余 | `expr $b % $a` 结果为 0。 |
= | 赋值 | a=$b 将把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true。 | [ $a == $b ] 返回 false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | [ $a != $b ] 返回 true。 |
7.4 关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 false。 |
-ne | 检测两个数是否相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true。 |
7.5 布尔运算符
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true。 | [ ! false ] 返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
7.6 逻辑运算符
以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的 AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
|| | 逻辑的 OR | [[ $a -lt 100 || $b -gt 100 ]] 返回 true |
7.7 字符串运算符
下表列出了常用的字符串运算符,假定变量 a 为 "abc",变量 b 为 "efg":运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
!= | 检测两个字符串是否相等,不相等返回 true。 | [ $a != $b ] 返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否为0,不为0返回 true。 | [ -n $a ] 返回 true。 |
str | 检测字符串是否为空,不为空返回 true。 | [ $a ] 返回 true。 |
7.8 文件测试运算符
操作符 | 说明 | 举例 |
---|---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | [ -c $file ] 返回 false。 |
-d file | 检测文件是否是目录,如果是,则返回 true。 | [ -d $file ] 返回 false。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | [ -f $file ] 返回 true。 |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | [ -g $file ] 返回 false。 |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | [ -k $file ] 返回 false。 |
-p file | 检测文件是否是有名管道,如果是,则返回 true。 | [ -p $file ] 返回 false。 |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | [ -u $file ] 返回 false。 |
-r file | 检测文件是否可读,如果是,则返回 true。 | [ -r $file ] 返回 true。 |
-w file | 检测文件是否可写,如果是,则返回 true。 | [ -w $file ] 返回 true。 |
-x file | 检测文件是否可执行,如果是,则返回 true。 | [ -x $file ] 返回 true。 |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | [ -s $file ] 返回 true。 |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | [ -e $file ] 返回 true。 |
八、Shell中的逻辑控制语句
1. if 语句
if commands; then commands elif commands; then commands else commands fi
2. for语句
for var in item1 item2 ... itemN do command1 command2 ... commandN done当变量值在列表里,for循环即执行一次所有命令,使用变量名获取列表中的当前取值。命令可为任何有效的shell命令和语句。in列表可以包含替换、字符串和文件名。in列表是可选的,如果不用它,for循环使用命令行的位置参数。
3. while语句
while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:
while condition do command done
4. util语句
until循环执行一系列命令直至条件为真时停止。until循环与while循环在处理方式上刚好相反。一般while循环优于until循环,但在某些时候—也只是极少数情况下,until循环更加有用。until 语法格式:
until condition do command done条件可为任意测试条件,测试发生在循环末尾,因此循环至少执行一次—请注意这一点。
5. case
Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。case语句格式如下:
case 值 in 模式1) command1 command2 ... commandN ;; 模式2) command1 command2 ... commandN ;; esaccase工作方式如上所示。取值后面必须为单词in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。
九、Shell中的测试语句
经常与 if 一块使用的命令是 test。test 命令执行各种各样的检查与比较,它有两种等价模式:test expression
或
[ expression ]
其中expression 为一个表达式,其执行结果是 true 或者是 false。当表达式为真时,这个 test 命令返回一个0退出状态,当表达式为假时,test 命令退出状态为1。
正则表达式和[[ expression ]]
目前的 bash 版本包含一个复合命令:[[ expression ]],与test相比增加了一个重要的新的字符串表达式:string1 =~ regex,若string1匹配扩展的正则表达式 regex则返回真#!/bin/bash # test-integer2: evaluate the value of an integer. INT=-5 if [[ "$INT" =~ ^-?[0-9]+$ ]]; then if [ $INT -eq 0 ]; then echo "INT is zero." else if [ $INT -lt 0 ]; then echo "INT is negative." else echo "INT is positive." fi if [ $((INT % 2)) -eq 0 ]; then echo "INT is even." else echo "INT is odd." fi fi else echo "INT is not an integer." >&2 exit 1 fi
整数复合命令(( ))
"(( ))"是专门为整数运算设计的复合命令,双括号内的运算符号(+、-、*、/、%)和比较符号(>、<)不需要转义即可使用。#!/bin/bash # test-integer2a: evaluate the value of an integer. INT=-5 if [[ "$INT" =~ ^-?[0-9]+$ ]]; then if ((INT == 0)); then echo "INT is zero." else if ((INT < 0)); then echo "INT is negative." else echo "INT is positive." fi if (( ((INT % 2)) == 0)); then echo "INT is even." else echo "INT is odd." fi fi else echo "INT is not an integer." >&2 exit 1 fi
十、Shell中的输入和交互
read - 从标准输入读取单行数据,read读取一个整数示例如下:echo -n "Please enter an integer -> " read var echo "var = '$var'"给多个变量赋值:
echo -n "Enter one or more values > " read var1 var2 echo "var1 = '$var1'" echo "var2 = '$var2'"若没有提供变量名,shell 变量 REPLY 会包含数据行
echo -n "Enter one or more values > " read echo "REPLY = '$REPLY'"read选项:read [-options] [variable...]
-a array:把输入赋值到数组 array 中,从索引号零开始
-d delimiter:用字符串 delimiter 中的第一个字符指示输入结束,而不是一个换行符
-e:使用 Readline 来处理输入。这使得与命令行相同的方式编辑输入
-n num:读取 num 个输入字符,而不是整行
-p prompt:为输入显示提示信息,使用字符串 prompt
-r:Raw mode. 不把反斜杠字符解释为转义字符
-s:Silent mode. 不会在屏幕上显示输入的字符。当输入密码和其它确认信息的时候,这会很有帮助
-t seconds:超时. 几秒钟后终止输入。read 会返回一个非零退出状态,若输入超时
-u fd:使用文件描述符 fd 中的输入,而不是标准输入
密码输入脚本
此脚本提示用户输入一个密码,若在10秒内没有完成输入,则脚本会退出并返回一个错误。因包含了一个 -s 选项,所以输入的密码不会出现在屏幕上。
#!/bin/bash if read -t 10 -sp "Enter secret pass phrase > " secret_pass; then echo -e "\nSecret pass phrase = '$secret_pass'" else echo -e "\nInput timed out" >&2 exit 1 fi输入校正
通过对输入的数据进行校验,得到期望范围内的输入
#!/bin/bash invalid_input () { echo "Invalid input '$REPLY'" >&2 exit 1 } read -p "Enter a single item > " # input is empty (invalid) [[ -z $REPLY ]] && invalid_input # input is multiple items (invalid) (( $(echo $REPLY | wc -w) > 1 )) && invalid_input # is input a valid filename? if [[ $REPLY =~ ^[-[:alnum:]\._]+$ ]]; then echo "'$REPLY' is a valid filename." if [[ -e $REPLY ]]; then echo "And file '$REPLY' exists." else echo "However, file '$REPLY' does not exist." fi # is input a floating point number? if [[ $REPLY =~ ^-?[[:digit:]]*\.[[:digit:]]+$ ]]; then echo "'$REPLY' is a floating point number." else echo "'$REPLY' is not a floating point number." fi # is input an integer? if [[ $REPLY =~ ^-?[[:digit:]]+$ ]]; then echo "'$REPLY' is an integer." else echo "'$REPLY' is not an integer." fi else echo "The string '$REPLY' is not a valid filename." fi菜单驱动
一种常见的交互类型称为菜单驱动,从逻辑上讲,这个脚本被分为两部分。第一部分显示菜单和用户输入。第二部分确认用户反馈,并执行 选择的行动
#!/bin/bash # read-menu: a menu driven system information program clear echo " Please Select: 1. Display System Information 2. Display Disk Space 3. Display Home Space Utilization 0. Quit " read -p "Enter selection [0-3] > " if [[ $REPLY =~ ^[0-3]$ ]]; then if [[ $REPLY == 0 ]]; then echo "Program terminated." exit fi if [[ $REPLY == 1 ]]; then echo "Hostname: $HOSTNAME" uptime exit fi if [[ $REPLY == 2 ]]; then df -h exit fi if [[ $REPLY == 3 ]]; then if [[ $(id -u) -eq 0 ]]; then echo "Home Space Utilization (All Users)" du -sh /home/* else echo "Home Space Utilization ($USER)" du -sh $HOME fi exit fi else echo "Invalid entry." >&2 exit 1 fi
十一、文件重定向
1. linux文件描述符
linux启动后,会默认打开3个文件描述符,分别是:标准输入 standard input 0
正确输出 standard output 1
错误输出 error output 2
这些默认的输出,输入都是linux系统内定的,我们在使用过程中,有时候并不希望执行结果输出到屏幕。我想输出到文件或其它设备。这个时候我们就需要进行输出重定向了。
2. 输出重定向
输出重定向的命令如下所示:command-line1 [1-n] > file或文件操作符或设备将一条命令执行结果(标准输出,或者错误输出,本来都要打印到屏幕上面的) 重定向其它输出设备(文件,打开文件操作符,或打印机等等)1,2分别是标准输出,错误输出。
#把错误输出,不输出到屏幕,输出到err.txt [zenhobby@zencode shell]$ ls test.sh test1.sh 1>suc.txt 2>err.txt [zenhhobby@zencode shell]$ cat suc.txt err.txt test.sh ls: test1.sh: 没有这个文件和目录 #继续追加把输出写入suc.txt err.txt “>>”追加操作符 [zenhobby@zencode shell]$ ls test.sh test1.sh 1>>suc.txt 2>>err.txt
输出重定向的命令如下所示:
命令 | 说明 |
---|---|
command > file | 将输出重定向到 file。 |
command < file | 将输入重定向到 file。 |
command >> file | 将输出以追加的方式重定向到 file。 |
n > file | 将文件描述符为 n 的文件重定向到 file。 |
n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file。 |
n >& m | 将输出文件 m 和 n 合并。 |
n <& m | 将输入文件 m 和 n 合并。 |
<< tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入。 |
2、“>>”操作符,判断右边文件,如果不存在,先创建。以添加方式打开文件,会分配一个文件描述符[不特别指定,默认为1,2]然后,与左边的标准输出(1)或错误输出(2) 绑定。
3、当命令:执行完,绑定文件的描述符也自动失效。0,1,2又会空闲。
4、一条命令启动,命令的输入,正确输出,错误输出,默认分别绑定0,1,2文件描述符。
5、一条命令在执行前,先会检查输出是否正确,如果输出设备错误,将不会进行命令执行
3. 输入重定向
输入重定向的命令如下所示:command-line <file或文件描述符&设备命令将默认从键盘获得的输入,改成从文件,或者其它打开文件以及设备输入。执行这个命令,将标准输入0,与文件或设备绑定。将由它进行输入。
[zenhobby@zencode shell]# cat > catfile testing cat file test #这里按下 [ctrl]+d 离开 #从标准输入【键盘】获得数据,然后输出给catfile文件 [zenhobby@zencode shell]$ cat>catfile <test.sh #cat 从test.sh 获得输入数据,然后输出给文件catfile [zenhobby@zencode shell]$ cat>catfile <<eof test a file test! eof #<< 这个连续两个小符号, 他代表的是『结束的输入字符』的意思。这样当空行输入eof字符,输入自动结束,不用ctrl+D
4. 重定向到空设备文件
Linux下使用shell命令时经常使用类似这样的Shell输出重定向:1>/dev/null 2>&11. 标准输入stdin文件描述符为0,标准输出stdout文件描述符为1,标准错误stderr文件描述符为2
2. /dev/null 空设备文件,相当于垃圾桶
3. >前面的数字:
0代表标准输入
1代表stdout标准输出,默认值为1,所以”1>/dev/null”可以简写为”>/dev/null”
2代表stderr标准错误输出
4. 2>&1代表把stderr标准错误输出 重定向 到stdout标准输出
所以,1>/dev/null 2>&1的解释就是:
将stdout标准输出重定向到空设备文件/dev/null ,同时将stderr标准错误输出的重定向跟stdout标准输出重定向一致,也输出到空设备文件/dev/null。
相关文章推荐
- Shell编程基础
- shell编程基础
- shell编程入门步步高(二、基础概念)
- shell编程基础(上)
- SHELL编程之语法基础
- shell编程基础自学知识(截取字符串) shell基础语法判断和循环等
- Ubuntu下shell编程基础
- Shell编程基础
- linux shell 学习笔记(三)--shell编程基础
- shell编程基础
- shell编程基础总结
- Linux下的shell编程(一)--基础
- Shell编程基础
- 企业shell编程基础问题解决实践
- shell编程基础知识
- shell编程基础
- Shell编程基础
- Linux_shell编程基础
- 【shell编程基础3】shell编程的组合应用之二:管道及其命令
- Shell编程基础