您的位置:首页 > 运维架构 > Shell

菜鸟的Linux之路3 bash脚本编程之二

2016-07-22 20:38 531 查看
整数测试及特殊变量
在开始之前我们先介绍一个可以提前结束脚本的命令->exit
exit的作用是退出当前进程、退出当前脚本,任何一个命令或者说是任何一个进程执行结束的时候都会有一个执行结果返回值和一个执行状态结果返回值,exit是用来让用户自定义执行状态结果返回值的命令。

命令、脚本或者说是进程的执行状态结果有两种情况:

->正确执行

->错误执行

而这种状态可以使用exit命令自定义。

exit命令使用格式:exit #(0-255)

0值,表示执行正确

1-255的值,均表示执行错误

使用exit+错误返回码可以提前退出脚本,表示条件不满足就直接退出脚本。

练习:写一个脚本,要求
1,给定一个用户,先判断用户是否存在;

如果用户不存在,则显示"No such user.",并自动退出脚本;

否则,判断用户的UID和GID是否相等

如果相等,则显示"good guy.";

否则,显示"bad guy."。

脚本内容:




脚本执行结果:




2,给定一个用户,先判断用户是否存在;

如果用户存在,则判断该用户的UID和GID是否相等

如果相等,则显示该用户为"good guy.";

否则,显示该用户为"bad guy."。

如果用户不存在,则显示"No such user.",并且直接退出脚本。

脚本内容:




脚本执行结果:




脚本中的grep命令:

锚定行首:^

锚定行尾:$

锚定单词首部:\<

锚定单词尾部:\>

bash中常用的条件测试有三种:

1,字符串测试

2,整数测试

3,文监测试

现在我们来说说整数测试:

整数测试是一个双目操作,因为它需要比较两个操作数的大小,常用整数测试操作符有以下几种:
-gt->大于
-le->小于等于
-ne->不等于
-eq->等于
-ge->大于等于
-lt->小于
测试方法:
eg->INT1=63,INT2=77
[ expression ]->命令测试法,一个中括号为bash的命令,中括号和表达式之间有空格,否则为语法错误。
->[ $INT1 -eq $INT2 ]
[[ expression ]]->关键字测试法,两个中括号为bash的关键字,一样得有空格。
->[[ $INT1 -eq $INT2 ]]
test命令测试法:test expression
->test $INT1 -eq $INT2
对if而言,if后面的条件测试的值为0时,条件才为真,否则全为假。

接下来我们来说说文件测试:
文件测试的选项
->-e(exist,单目操作符)FILE,测试一个文件是否存在。

[ -e /etc/inittab ]

->-f FILE,测试一个文件是否为普通文件。

->-d FILE,测试指定路径是否为目录。

->-r FILE,测试当前用户对指定文件是否有读权限。

->-w FILE,测试当前用户对指定文件是否有写权限。

->-x FILE,测试当前用户对指定文件是否有执行权限。

[ -x /etc/rc.d/rc/sysinit ]

练习:写一个脚本,要求

给定一个文件,先判断文件是否存在;

如果文件不存在,则显示该文件不存在,并且直接退出脚本;

如果文件存在,则判断该文件中是否存在空白行;

如果存在空白行,则显示空白行的行数;

否则,显示该文件中没有空白行。

脚本内容:




脚本执行结果:




练习:写一个脚本,要求

给定一个用户,获得其密码警告期限

先判断用户密码的使用剩余期限是否小于密码警告期限

如果小于,则显示"Warning.";

否则,显示"OK."。

脚本内容:




脚本执行结果:





圆整:bash在做运算的时候,会直接丢弃小数点之后的内容。

练习:写一个脚本,要求:
判断命令历史中的总条目是否大于1000;
如果大于,则显示"Some command will gone.";

否则,显示"OK."。

脚本内容:




脚本执行结果:





history命令只能保留最近1000条命令。

多分支的if语句

格式:

if 判断条件1

then

statement1

...

elif 判断条件2
then

statement2

...

elif 判断条件3

then

statement3

...

...

else

statement4

...

fi

bash中测试脚本是否有语法错误的方法

格式:

->sh -n 脚本名称 但是这种方法无法测试脚本中的关键字错误,但是报错未必可靠。

->sh -x 脚本名称 这种方法又称为单步执行

练习:写一个脚本,要求

给定一个文件,判断文件是否存在;

如果文件存在,则进行如下判断

如果是普通文件,则显示该文件为普通文件;

如果是目录,则显示该文件为目录;

否则,显示此为无法识别的文件。

如果文件不存在,则显示"No such file.",并且直接退出脚本。

脚本内容:




脚本执行结果:





文件测试中,如果文件存在,则正确退出,脚本执行状态返回值为0;如果文件不存在,则错误退出,返回的脚本执行状态返回值使我们自定义的。

定义脚本退出状态码

如果在脚本中没有明确定义退出状态码,那么最后执行的一条命令的退出码即为脚本的退出状态码,可以利用echo $?查看。

如果exit后面没有加数字,那么脚本的执行状态返回值可能为0,因为最后一条命令有可能是正确执行的。

bash变量类型分为以下几种:

1,本地变量(本地变量的概念大于局部变量的概念)

2,环境变量

3,位置变量:$1,$2,...

->位置变量引用脚本的作用对象:

$1引用脚本的第一个参数

$2引用脚本的第二个参数

...

eg->

sh xxx.sh /etc/fstab /etc/inittab

$1->/etc/fstab

$2->/etc/inittab

shift->轮换、轮替。

练习:写一个脚本,要求

脚本可以接收一个参数

判断:此参数如果是一个存在的文件,就显示"OK.";

否则,就显示"No such file."。

脚本内容:





脚本执行结果:




上面的脚本中加入了一个如果用户没有给脚本传递参数,则脚本就不会执行这一功能。

特殊变量

$?->显示进程的执行状态返回值

$#->显示传递参数的个数

$*->显示参数列表,把传递的参数显示出来

$@->参数列表,单和上面的特殊变量有所不同

练习:写一个脚本,要求

给脚本传递两个参数(整数):

显示此两者之和,之积。

脚本内容:




脚本执行结果:





sed命令

linux三大基本文本处理工具:
->grep:过滤

->sed:数据流编辑器

->awk:报告文本的生成器

sed(stream editor->流编辑器,行编辑器)基本用法:

字处理器和文本编辑器是两码事,sed是文本编辑器,用来操作纯ASICLL码的。

sed操作文本的时候是按行进行的,逐行进行操作的,主要功能只用来逐行处理文本。

编辑器分为两类:

1,行编辑器

2,全屏编辑器:vi

sed的处理机制

->并不直接处理文本文件本身,每当处理一个文件的时候,它把文件逐行读取,一次把文本文件的一行内容读取到内存空间中去,在内存中完成编辑,并把编辑的结果输出到屏幕上。

->对sed而言,这段内存空间称为模式空间。

sed在处理文件的每一行的时候,不是文件的每一行都处理的,它可以指定仅处理哪些行,而这些行也可以像grep一样做模式过滤的,像grep一样,符合模式条件的行才处理,不符合模式条件的行不予处理,因此这段内存空间称为sed的模式空间。

sed在处理文件的时候,它会把符合模式条件的行读进模式空间中去匹配,或者把每一行内容都读进模式空间去和模式条件进行匹配,如果可以被模式条件匹配到,就在模式空间中使用后面的编辑命令对其完成编辑,将编辑的结果输出到屏幕上来,sed中有很多子编辑命令。

默认情况下,sed不编辑原文件,仅对模式空间中的数据做处理,而后将模式空间中的内容打印至屏幕。

用法:地址+命令。

sed脚本->sed也是一种语言,对文件做编辑的语言。

格式:sed [options] 'address(对哪些行做处理,它和后面的命令之间不需要空白字符)command(编辑命令)' file ...

sed命令的选项

-n:静默模式,不再默认显示模式空间的内容,只显示符合条件的行

因为sed命令在处理完文本后默认会将模式空间中的内容全部打印至屏幕,所以使用p命令的时候会将匹配到的内容在屏幕上打印两次。

-i:sed命令默认是不会修改原文件的,而-i选项可以用来修改原文件。

功能:直接修改原文件。

-e:用法格式

->-e script -e script:可以同时执行多个脚本,sed命令中单引号的部分称为脚本。

-f:把多个要执行的脚本可以写在一个文件里面,这个文件里面每一行就是一个脚本,然后使用-f选项读取这个文件也能够执行相应的操作。

->sed后面跟单引号,双引号都可以,但是如果引号里面有变量,且需要进行变量替换的时候就必须使用双引号。

用法格式:-f /path/to/sed_script

sed -f /path/to/scripts file

-r:默认情况下sed只支持基本的正则表达式,要想使用扩展的正则表达式的时候就得使用-r选项。

功能:使用扩展的正则表达式。

sed脚本中的地址:address

功能:对后面文件中的符合地址指定的行,做出命令编辑。

用法:

->起始行 逗号隔开 结束行:指定起始行到结束行之间的行数。

eg:1,100 表示从第一行到第一百行。

$ 表示指定最后一行。

$-1 表示指定倒数第二行,依次类推。

->使用模式/regexp/->斜线里面是正则表达式。

匹配时只要和元字符冲突的时候就要使用\进行转译,显示元字符本身的功能。

eg->/^root/ 表示匹配以root开头的行。

->起始行和结束行也可以如此来定义。

/pattern1/,/pattern2/->表示这个文件中从第一次被第一个模式匹配到的行开始,到第一次被第二个模式匹配到的行结束的所有行数。

->只跟一个行号,表示精确匹配某行。

功能:指定某行。

->起始行,+N

功能:匹配从指定行开始到向后的N行。

sed命令中的编辑命令:command

d:删除符合模式匹配条件的行,符合模式匹配条件的删除,不符合模式条件的还留在模式空间中,最后不符合条件的全部打印至屏幕。

p(打印命令):将符合条件的行打印至标准输出。

a:用法格式->a \string

功能:在模式匹配条件指定的行后面指定新行,内容为"string",想要再添加新行的话就得加上换行符\n,后面再加上"string"。

\n->换行符,可用于换行。

i:用法格式->i \string

功能:在模式匹配条件指定的行前面添加新行。

r:用法格式->r file

功能:用于合并文件,将指定文件的内容添加至符合条件的行处。
w:用法格式->w file
功能:将指定范围内的内容另存至指定的文件中。
s:功能->查找并替换。
用法格式->s/pattern(正则表达式元字符)/string(将匹配到的字符串替换成string)/修饰符
s命令的分隔符,不仅仅只是用斜线,可以使用任意的符号,只要三个分隔符一样就可以,它可以像grep命令一样去使用后向引用。

&->引用模式匹配到的整个字符串。

后向引用

->模式->\(aaa\),替换字符串为\1,再跟上要加的字符,有些时候必须使用后向引用而不能使用&。

eg:将sed.txt中的l..e字符串中的l全部替换为L,要将所匹配内容的部分替换就得使用后向引用。

->sed 's/l\(..e\)/L\1/g' sed.txt->后向引用的用法:将除过想要替换部分的其余部分用括号括起来。

s命令默认只替换每一行中第一次被模式匹配条件匹配到的字符串,如果要替换每一行中所有被模式匹配条件匹配到的字符串得使用修饰符。

->g:表示全局替换

->i:表示查找时忽略字符的大小写

练习:使用history命令将所有的历史命令号码提取出来。

命令及命令执行结果:





sed练习

1,删除/etc/grub.conf文件中行首的空白符。

命令及命令执行结果:




2,删除/etc/inittab文件中的空白行。

命令及命令执行结果:




3,删除/etc/inittab文件中开头的#号。

命令及命令执行结果:




4,删除某文件中开头的#号及空白字符,要求#号后面必须要有空白字符。

提示:+->表示匹配其前的字符至少一次

命令及命令执行结果:




文件的纯文件名又叫做文件的基名。

字符串测试:

->==:比较两个字符串是否相等,比较时等号两边要有空格。

->!=:比较两个字符串是否不等。

->>

-><

->-n string:测试指定字符串是否为空,空则真,不空则假。

->-s:测试指定字符串是否不空,不空为真,空则为假。

练习:写一个脚本,要求:

传递一个用户名参数给脚本;

判断此用户的用户名和基本组的组名是否一致,并将结果显示出来。

tips->id -n -u 显示用户的用户名;

id -n -g 显示用户基本组的组名。

脚本内容:




脚本执行结果:




练习:写一个脚本,要求:

传递一个字符给脚本,如果参数为q、Q或者是quit、Quit,就退出脚本,否则就显示用户的参数。

脚本内容:




脚本执行结果:





使数值计算计算结果保留两位精度的方法->

echo "scale=2;xxx/xxx;" | bc

bc <<< "scale=2;xxx/xxx;"

Linux循环控制结构
循环控制结构一定要有进入循环的条件和退出循环的条件。

bash中油三种循环:

->for循环

用法格式:

for 变量 in 列表

do

循环体

done

当列表被遍历完成后,就退出循环。

如何生成列表:

1,{1..100}表示1-100之间的所有整数,步长为1。

2,seq(sequence)命令->命令功能:自动生成列表。

用法格式:

`seq [起始数] [步进长度] <结束数>` ->要想在for循环中生成列表,seq命令得使用命令替换。

bash不支持浮点运算,只支持整数间的运算。

declare(声明) -i(integer->整型数) SUM=0 -> 将变量声明为整数,并赋值。
-x(export->环境变量) -> 将变量声明为环境变量。

bash中变量默认为字符型,需要使用let命令,转换为数值赋值进行操作,也可以使用上面的declare声明进行操作。

->while循环
->until循环

练习:写一个脚本,要求:
对系统的每一个用户问好。
脚本内容:



脚本执行结果:





head命令,不加任何选项默认查看文件的前10行。

-n:该选项加行数,可以查看前几行。

seq命令的默认步长为1.

本文出自 “菜鸟的技术文档” 博客,请务必保留此出处http://zhubo.blog.51cto.com/11395641/1828955
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: