首页 > 代码库 > shell脚本等的操作

shell脚本等的操作

1、命令替换:``

反向单引号,也称重音符。键盘上和~键在一起的那个键呦,千万不要敲成单引号。

A、

技术分享

使用了``后,shell首先替换输出中``括起来的date命令,然后执行整个输出命令。

B、命令替换还可以用于在变量中存储命令输出,如下:

技术分享

变量ctr将包含当前目录中名字以.txt结尾的文件的计数。

2、expr

大部分shell不支持数字变量,所有变量会被作为字符串。如var=25,变量var中包含的是字符2和字符5组成的字符串,而不是数字25.

Expr命令用来评估算术表达式,命令的输出发送到标准输出。

技术分享

如上图所示,expr 4 + 5进行整数的加法运算,输出9.

技术分享

expr命令支持的算术运算符有:+ 、-、 *、 /、 %。但是*需要使用\进行转义,否则shell会将*作为通配符处理,如下图所示:

技术分享

注意:使用expr命令是,算术运算符的左右两边必须添加一个空格。如下图所示,不添加空格时,不会进行算术运算:

技术分享

此外,expr命令只支持整数运算,不支持小数,如下所示,使用小数无法获取正确算术运算结果:

技术分享

expr命令的输出将发送到标准输出,若想输出存储到变量中,可以结合命令替换使用:

技术分享

3、typeset-i

Bash和ksh shell对整数变量提供有限的支持。我们可以使用typeset –i 变量名定义一个整数变量,可以直接使用该整数变量进行算术运算。

技术分享

4、评估表达式,返回”   test/[](方括号)

通常会使用test或[]用来评估条件是否成立。语法如下:

test 表达式

[ 表达式 ]

注意test之后先加空格,再写表达式。使用[]时,表达式的左右两边都需要添加空格。表达式的比较运算符左右两边都需要添加一个空格。

表达式里包含多个条件时,可以使用选项-a和-o:

-a:条件同时成立,与,and的意思,

-o:一个条件成立即可,或者,or的意思

test/[]主要用在编程构造中,所以我们在下面的编程构造部分,具体展示其用法。

5、if构造

if构造作用和java中的if语句一样,语法有所区别

if构造语法:

if condition(s)

then command(s)

[ else command(s) ]

fi

if构造必须以fi结尾,else部分不是必须的,具体看使用场景。

if…elif构造

if condition(s)

then command(s)

elif command(s)

else command(s)

fi

if构造可以有多个elif语句,但只能有一个fi来结束构造,else最多也只能有一个。

课堂练习:

在shell脚本中,脚本文件名字叫testif.sh,实现以下功能:

1、提示用户输入成绩

2、读取用户输入的成绩放到变量mark中

3、如果mark>= 80,提示用户“you are excellent!”

mark>= 70 && mark <80, 提示“hei,guy,you are good.”

mark >= 60 && mark < 70, 提示“it is ok.”

mark <60 , 提示 “oh, guy ,it is so bad,you should work hard.”

算术测试中的比较运算符使用以下选项表示

等于                                      -eq

不等于 -ne

大于等于                             -ge

大于                                      -gt

小于等于                             -le

小于                                      -lt

以下为shell脚本文件中语句:

技术分享

代码执行效果:

技术分享

其中判断条件书写时,除了使用test,也可以使用[],如:

技术分享

6、case构造

case … esac构造语法为:

case $variable-name in

       value1)   command(s) ;;

       value2)   command(s) ;;

       .

       .

       .

      *)   command(s) ;;

Esac

该构造用于在shell脚本中根据变量值执行特定的指令集,评估变量的值,并将其与指定的每个值比较。当变量值与指定值之一匹配时,将执行在该值下指定的命令集。

课堂练习:

1、编写一个shell脚本,文件名字为testcase.sh

2、第一行提示用户输入数字年级:

在提示信息的同一行读取用户输入的年级,放到变量grade里

3、如果用户输入的是1,就显示freshman

如果用户输入的是2,就显示sophomore

如果用户输入的是3,就显示junior

如果用户输入的是4,就显示senior

如果用户输入的是其他的内容,显示ni cai

要求本功能使用case实现。

以下为shell脚本文件中语句:

技术分享

使用case构造时,为任何变量值执行的最后一个命令后必须加一对分号,用于分隔为下一个值执行的命令集中的命令。

7、while构造

while循环的语法:

while  condition(s)

do

      command(s)

done

这里,只要条件为真,就执行do和done中间的命令。

break和continue语句

break和continue命令可以用于while循环。break表示退出整个循环,continue表示退出当前循环,开始下一次循环。

技术分享

执行效果如下图所示:

技术分享

课堂练习:

1、编写一个shell脚本,文件名字为testwhile.sh

2、使用while循环打印出1——10之间的数字

以下为shell脚本文件中语句:

技术分享

或者:

技术分享

执行效果:

技术分享

8、until构造

until用法和while一样,但是是条件不成立时,即条件为假时,才进入循环,条件为真时,结束循环。

9、for构造

for循环语法:

for variable_name in <list_of_values>

do

       …

       …

Done

for循环将一列值作为输入,并为循环中的每个值执行该循环,即执行do … done之间的命令。

for循环中的一列值由一个或多个空格分隔。1——9可以用{1..9}表示

课堂练习:

编写shell脚本文件,输出九九乘法表:

技术分享

echo命令后面选项e的作用是让后面的字符’\t’显示成特殊字符,即tab键,而不是作为普通文本输出。

执行效果:

技术分享

补充:seq

Seq语句用于产生从某个数据到另外一个数据之间的所有整数,即序列,并可以指定序列中相邻两个整数之间的差值即序列增长的步幅。当只指定序列的起始值和结束值时,步幅为1;当只指定一个数值时,默认该指定数值为结束值,序列默认从1开始,步幅为1;当指定需要指定步幅时,需要先指定起始值,再指定步幅,最后指定结束值。如下图所示:

技术分享

将上面九九乘法表中的内层循环改成for循环,就可以在内层循环中使用seq语句的输出作为内层循环所需要进行循环的列值:

技术分享

10、exit

exit基于测试命令的结果从shell脚本退出,即停止执行并返回$提示符。exit命令可以用在if构造的if或者else部分中。

技术分享

上面脚本执行结果:

技术分享

当用户输入y时,退出,不在执行echo “you want to quit.” 语句。

另外,exit命令还可以写成exit n,n为任意整数。其中整数0表示成功,其他非0值表示不同的失败原因。在上面九九乘法表中,就使用到了exit 0。

11、test命令复习

test命令除了和if或while等构造结合使用,检查变量的值之外,还有另外三种用法:

A、test命令选项测试文件状态

测试文件状态的各选项,这里不一一列举,见课本6.11页。

下面列举一个例子:

技术分享

上面脚本执行效果:

技术分享

B、test用于算术测试

test命令与if结合,可以测试变量的数值,各选项代表的算术测试运算符和用法已在上面if构造部分演示。

C、test命令可以测试字符串

字符串测试运算符见课本6.13页。

12、创建函数

函数是由同一名称引用的并用于执行特定任务的语句块。需要重复执行同一任务时,应该为该任务创建一个函数,通过指定函数名来调用函数。函数必须先定义再调用。

定义函数语法:

function <function_name>

{

    <commands>

}

(1)在shell脚本文件中定义函数f1,并添加调用函数语句。函数可以在shell脚本文件中,函数定义之后,可以通过函数名字调用:

技术分享

执行上面脚本文件后:

技术分享

(2)在命令符提示后,定义函数f2,并调用函数

技术分享

(3)将参数传递给函数。使用它们的位置来引用传递给函数的参数,即利用定义函数时使用位置参数。

在shell脚本文件中定义函数listdir、viewfile、cpfile

技术分享

如果只在shell脚本文件中定义函数,没有调用函数语句,那么执行shell脚本文件时,只是创建了函数,不会调用。并且在当前shell即命令提示符之后,也不能直接调用这些函数。

执行source 脚本文件名字 语句后,就可以在当前shell中调用定义的函数了。如下所示:

技术分享

关于位置参数,将在下面演示。

13、处理shell脚本中的参数

参数用于将自变量从命令行传递到shell脚本。参数可以是任何值,通常是文件名或字符串,它是在shell提示符后指定的一个命令名或文件名。在脚本中,作为一个自变量来引用参数。

         Shell按照Liunx解释命令,输入命令并按回车后,shell会以以下方式将命令行中的每个词放入到特殊变量:

命令行中的第一个词,即命令名,会被放入称为$0的变量。

命令行中的第一个参数,即命令行中的第二个词,被放入变量$1中。

命令行中的第二个参数,即命令行中的第三个词,被放入变量$2中。

除$0之外,shell最多可以正确创建9个变量,9个之后存储的值将不再准确。$1到$9也称为命令行的位置参数。根据命令中指定的参数的数量,shell将值赋给这些变量中的一些或全部。

Shell还会为以下变量赋值:

         $*:包含整串参数

         $#:包含命令中指定参数的数量

下面简单演示如何设置位置参数:

技术分享

执行效果如下:

技术分享

使用位置参数,实现复制文件:

技术分享

执行效果:

技术分享

14、shift命令

Shell最多只创建9个位置参数,即$0--$9。从第10个开始参数存储的值将不再正确。

如下所示,测试用户输入参数超过9的场景:

技术分享

执行脚本文件,输入多个参数,发现$10参数存储的值为$1参数追加0,$11参数存储的值为$1参数追加1,这和实际输入不相符:

技术分享

实际中,可能会发生用户输入参数超过9个情况,shift命令可以允许用户输入可变数量的参数,包括超过9个场景,shift可以使用多次。

技术分享

本例中shift命令效果讲解:

技术分享

本例用来帮助用户复制或函数文件,如果脚本文件名字之后输入c表示用户想要复制文件,输入d表示用户想要删除文件。输入其它时,给用户提示参数只能是c或d.

执行效果如下:

技术分享

15、.bash_file文件

.bash_file文件是特殊的 文件,用户一登录系统时即执行此脚本。该文件可选,存在用户的 home目录中,是隐藏文件,ls命令中,-a选项可以查看隐藏文件:

技术分享

16、here文档

对命令或shell脚本的输入通常包含在一个单独的文件中,然后会作为参数提供给脚本。还能将输入数据包含在shell脚本自身中,然后数据被认为是在一个here文档中,即输入就在这里,而不是在其他地方的某个文件中。<<运算符实现此类构造。

<<运算符用法:

command  << pattern

pattern

上面两个pattern中之间 的内容视为输入,所以pattern必须成对出现,如果缺少第二个,则会认为从第一个pattern至文件末尾的内容全部都是输入内容,不会认为是特殊命令。

pattern只是起一个标识作用,可以用任何字符串来表示。第二个pattern需要定格写。

Here文档的一种用法是显示菜单,与使用多条echo语句相比,here文档是构建菜单屏幕的有效方式。

我们使用here文档改写一下前面的带选择菜单的while循环:

技术分享

执行效果:

技术分享

17、调试shell脚本

使用set命令结合-x、-v选项调试shell脚本。

下面演示在sh <filename> 命令中调用-x 或-v选项:

sh-v <filename>

技术分享

执行脚本时,首先显示脚本中书写的每行语句,然后显示执行语句后的结果

sh-x <filename>

技术分享

与sh -v <filename>类似,也是将shell文件中书写的每行语句显示出来,但是-x选项会在每行语句前面加+,并且还会对每个语句和表达式进行变量值的替换,然后显示语句的执行结果。

shell脚本等的操作