linux之shell脚本管理(一)

在Shell脚本中执行使用if语句的好处是:可以根据特定的条件(eg:判断备份目录是否存在)来决定是否执行某项操作,当满足不同的条件时执行 不同的操作(eg:备份目录不存在则创建该目录,否则跳过操作)。该文将分别从条件测试操作,if语句结构,应用示例这三个方面讲解if语句在Shell 脚本中的应用。

1、条件测试操作:

需要在Shell脚本中有选择性地执行任务时,首先面临的问题就是,如何设置命令执行的条件?

在Shell环境中,可以根据命令执行后返回状态值来判断该命令是否成功执行,当返回值为0是表示成功执行,否则(非0值)表示执行失败。用于特定条件表达式的测试时,可以使用Linux系统中提供的专用工具——test命令、

使用test测试命令时,可以有以下两种形式。

test       条件表达式

【 条件表达式 】

这两种方式的作用完全相同,但通常后一种形式更为常用,也更贴近编程习惯。需要注意的是,方括号“[”或者“]”与条件表达式语句之间至少需要有一个空格进行分隔。

根据需要判断的条件内容不同,条件操作也不同,最常用的条件主要包括文件状态测试,比较整数值大小,比较字符串,以及同时判断多个条件时的逻辑关系,下面将分别进行讲解。以下主要采用方括号的测试形式。

1.1、测试文件状态

文件状态测试是指根据给定的路径名称,判断该名称对应的是文件还是目录,或者判断文件是否可读,可写,可执行等。根据判断的状态不同,在条件表达式中需要使用不同的操作选项。

-d:测试是否为目录(Directory)。

-e:测试目录或文件是否存在(Exist)。

-f:测试是否为文件(File)。

-r:测试当前用户是否有权限读取(Read)。

-w:测试当前用户是否有权限写入(Write)。

-x:测试当前用户是否可执行(Excute)该文件。

-L:测试是否为符号连接(Link)文件。

执行条件测试操作以后,通过预定义变量“$?”可以获得测试命令的返回状态值,从而能够判断该条件是否成立(返回0值表示条件成立,非0值表示条件不成立)。但通过这种方式查看测试结果会比较繁琐。

例1:测试“/etc/hosts”是否是文件,并通过“$?”变量查看返回状态值,据此判断测试结果。


1

2

3


[ -f /etc/hosts ]

echo $?

0  
//返回值为0,表示上一步测试的条件成立。

例2:测试“/media/cdrom/Server”及其父目录是否存在,如果存在则显示“YES”否则不输出任何信息。


1

2

3

4


[ -e /media/cdrom/Server ] && echo
"YES"

                                                                        
// 无输出表示该目录不 存在

[ -e /media/cdrom ] && echo
"YES"

YES

1.2、整数值 比较:

整数值比较是指根据给定的两个整数值,判断第一个数是否大于、等于、小于。。。。。。第2个数,可以使用的操作选项如下:


1

2

3

4

5

6


-eq:第一个数等于(Equal)第二个数。

-ne:第一个数不等于(Not Equal)第二个数。

-gt:第一个数大于(Greater Than)第二个数。

-lt:第一个数小于(Lesser Than)第二个数。

-le:第一个数小于或等于(Lesser or Equal)第二个数。

-ge:第一个数大于或等于(Greater or Equal)第二个数。

整数值比较的测试操作在Shell脚本编写中的应用较多,如:用于判断磁盘使用率、登录用户数量是否超标以及用于控制脚本语句的循环次数等。

例1:测试当前登录到系统中的用户数量是否小于或等于10,是则输出”YES“。


1

2

3

4


who | wc -l

5

[ `who | wc -l` -le
10
] && echo ”YES"

YES

例2:提取出"/boot“分区的磁盘使用率,并判断是否超过95%(为了便于理解,操作步骤适当进行分解)


1

2

3

4

5

6


df -hT | grep ”/boot“ | awk
‘{print $6}‘

12
%

BootUsage=`df -hT | grep ”/boot
" | awk ‘{print $6}‘ | cut -d "
%" -f
1
`

echo $BootUsage

12

[ $BootUsage -gt
95
] && echo
"YES"   
//无输出表示未超标

1.3:字符串比较:

字符串比较可以用于检查用户输入,如:在提供交互式操作时,判断用户输入的选项是否与指定的变量内容相匹配。“=”、“!=”操作选项分别表示匹配、不匹配。“-z”操作选项用于检查字符串是否为空。其中,“!”符号用于取反,表示相反的意思。

eg:提示用户输入一个文件路径,并判断是否是“/etc/inittab”,如果是则显示“YES”.


1

2

3

4


read -p
"Location: "
FilePath

Location: /etc/inittab           

[ $FilePath =
"/etc/inittab"
] && echo
"YES"

YES

eg: 若当前环境变量LANG的内容不是“en.US”,则输出LANG变量的值,否则无输出。


1

2


[ $LANG !=
"en.US"
] && echo $LANG

zh_CN.UTF-
8

eg: 使用touch命令建立一个新文件,测试其内容是否为空,向文件中写入内容后,再次进行测试。


1

2

3

4

5

6


touch zero.file

[ -z `cat zero.file` ] && echo
"yes"

yes

echo
"something"
> zero.file

[ -z `cat zero.file` ] && echo yes

                                                   
//无输出

1.4:逻辑测试:

逻辑测试是指同时使用的两个(或多个)条件表达式之间的关系。用户可以同时测试多个条件,根据这些条件是否同时成立或者只要有其中一个条件成立等情况,来决定采取何种操作。逻辑测试可以使用的操作选项如下。

>  &&:逻辑与,表示前后两个表达式都成立时整个测试结果才为真,否则结果为假。在使用test命令形式进程测试时,此选项可以改为" -a"。

>   ||:逻辑或,表示前后两个条件至少有一个成立时整个测试结果即为真,否则结果为假。在使用test命令形式进行测试时,此选项可以改为"-o“。

>  !:逻辑否,表示当指定的条件表达式不成立时,整个测试命令的结果为真。

在上述逻辑测试的操作选项中,”&&“和”||“通常也用于间隔不同的命令操作,其作用是相似的。同时使用多个逻辑运算操作时,一般安装从左到右的顺序进行测试。

eg:测试当前的用户是否是teacher,若不是则提示”Not teacher“。


1

2

3

4


echo $USER

root

[ $USER = “teacher” ] || echo
"Not teacher"

Not teacher

eg:只要"/etc/rc.d/rc.local"或者"/etc/init.d/local‘中有一个是文件,则显示"YES",否则无任何输出。


1

2


[ -f /etc/rc.d/rc.local ] || [ -f /etc/init.d/rc.local ] && echo "yes“

yes

eg:测试”/etc/profile“文件是否有可执行权限,若确实没有可执行权限,则提示”No x mode.“的信息。


1

2


[ ! -x ”/etc/profile
" ] && echo "
No x mode."

No x mode.

eg:若当前的用户是root且使用的Shell程序是"/bin/bash",则显示"YES“,否则无任何输出。


1

2

3

4


echo $USER $SHELL

root /bin/bash

[ $USER = ”root
" ] && [ $SHELL = "
/bin/bash
" ] && echo "
yes"

yes

2:if语句的结构:

前 面内容知道了一下条件测试操作,实际上使用"&&“和”||“逻辑测试可以完成简单的判断并执行相应的操作,但是当需要选择执行的命令语 句较多时,再使用这种方式将使命令行语句显得很复杂,难以阅读。而使用if语句,则可以更好地体现有选择性执行的程序结构,使得层次分明,清晰易懂。

if语句的选择结构由易到难可以分为三种类型,分别适用于不同的应用场合。

2.1、单分支的if语句。

单分支的if语句是最简单的选择结构,这种结果只判断指定的条件,当”条件成立“时执行相应的操作,否则不做任何操作。单分支使用的语句格式如下。

if 条件测试命令

then

命令序列

fi

在上述语句中,首先通过判断条件测试命令的返回状态值是否为0(条件成立),如果是,则执行then后面的一条或多台可执行语句(命令序列),一直到fi为止表示结束,如果条件测试命令的返回值不为0(条件不成立),则直接去执行fi后面的语句。

2.2、双分支的if语句。

双分支的if语句使用了两路命令操作,在”条件成立‘、“条件不成立时分别执行不同的命令序列”。双分支使用的语句格式如下:

if 条件测试命令

then

命令序列1;

else

命令序列2;

fi

在 上述语句中,首先通过if判断条件测试命令的返回状态值是否为0(条件成立),如果是,则执行then后面的一条或多条可执行语句(命令序列1),然后跳 转至fi结束判断,如果条件测试命令的返回状态值不为0(条件不成立),则执行else后面的语句,一直到fi表示结束。

2.3、多分支的if语句。

由于if语句可以根据条件测试命令的两种状态分别进行操作,所以能够嵌套使用,进行多次判断(如:首先判断某学生的得分是否及格,如及格则再次判断是否高于90分。。。)多重分支使用的语句格式如下。

if 条件测试命令1

then

命令序列1

elif 条件测试命令2

then

命令序列2

else

命令序列3

fi

上面的语法格式中只嵌套了一个elif语句,实际上if语句中可以嵌套多个elif语句。if语句的嵌套在编写Shell脚本时并不常用,因为多重嵌套容易使程序结构变得复杂。需要使用多重分支程序结构时,更多的是使用case语句来实现。

eg:检查"/var/log/messages‘文件是否存在,若存在则统计文件内容的行数并输出,否则不做任何操作。


1

2

3

4

5

6

7


vi  chklog.sh

#!/bin/bash

LogFile=
"/var/log/messages"

if
[ -f $LogFile ] ; then

wc -l $LogFile

fi

sh chklog.sh               
//sh是bash的符号链接

eg:提示用户指定备份目录的路径,若目录已存在则显示提示信息后跳过,否则显示相应提示信息后创建该目录。


1

2

3

4

5

6

7

8

9


[root@master ~]# vi mkbak.sh

#!/bin/bash

read -p
"What is your directory:"
Bakdir

if
[ -d $Bakdir ] ; then

echo
"$Bakdir already exist."

else

echo
"Bakdir is not exist,will make it."

mkdir $Bakdir

fi

eg:统计当前登录到系统中的用户数量,并判断是否超过三个,若是则显示实际数量并给出警告信息,否则列出登录的用户账号成名及所在终端。


1

2

3

4

5

6

7

8

9


[root@localhost ~]# vim chkuser.sh

#!/bin/bash

UserNum=`who |wc -l`

if
[ $UserNum -gt
3
] ; then

echo
"Alert , too many login users ( Total: $UserNum )."

else

 
echo
"Login users:"

 
who | awk
‘{print $1,$2}‘

fi

eg:检 查portmap进程是否已经存在,若已经存在则输出“portmap service is running”;否则检查是否存在“/etc/rc.d/init.d/portmap”可执行脚本,存在则启动portmap服务,否则提示“no portmap script file.”。


1

2

3

4

5

6

7

8

9

10

11


[root@localhost ~]# vim chkportmap.sh

#!/bin/bash

pgrep portmap &> /dev/
null

if
[ $? -eq
0
]; then

echo
"protmap service is running."

elif

[ -x
"/etc/rc.d/init.d/portmap"
]; then

service portmap start

else

echo
"no portmap script file."

fi

eg:每隔五分钟监测一次mysqld服务程序的运行状态,若发现mysqld进程已终止,则在“/var/log/messages”文件中追加写入日志信息(包括当时时间),并重启mysqld服务,否则不进程任何操作。


1

2

3

4

5

6

7

8

9

10


vi chkmysql.sh

#!/bin/bash

service mysqld status &> /dev/
null

if
[ $? -ne
0
]; then

echo
"At time:`date`:Mysql Server is down."
>> /
var
/log/messages

service mysqld restart

fi

chmod u+x chkmysql.sh

crontab -e

*/
5
* * * * /root/chkmysql.sh

3、使用for魂环语句

在Shell脚本中使用for循环语句时,可以为变量设置一个取值列表,每次读取列表中不同的变量值并执行相关命令操作,变量值用完以后则退出循环。Shell中的for语句不需要执行条件判断,其使用变量的取值来自于预先设置的值列表。

for语句结构:

for 变量名 in 取值列表

do

命令序列

done

在 上述语句中,使用in关键字为用户自定义变量设置了一个取值列表(以空格分隔的多个值),for语句第一次执行时首先将列表中的第一个取值赋给该变量。然 后执行do后边的命令序列;然后再将列表中的第二个取值赋给该变量,然后执行do后边的命令序列......如此循环,直到取值列表中的所有值都已经用 完,最后将跳至done语句,表示结束循环。

for语句示例:

eg:依次输出三条文件信息,包括一天中的"Morning"、"Noon"、"Evening"字串。


1

2

3

4

5

6


vi showday.sh

#!/bin/bash

for
TM
in
"Morning"
"Noon"
"Evening"

do

echo
"The $TM of the day."

done

eg:对于使用“/bin/bash”登录Shell的系统用户,检查他们在"/opt"目录中拥有的子目录或文件数量,如果超过100个,则列出具体数量及对应的用户账号。


1

2

3

4

5

6

7

8

9

10

11

12

13

14


vi chkfileown.sh

#!/bin/bash

DIR=
"/opt"               
//设置检查的目标目录

LMT=
100               
//设置文件数量的限制值

ValidUsers=`grep
"/bin/bash"
/etc/passwd | cut -d
":"
-f
1
`               
//找出使用bash的系统用户列表

for
UserName
in
$ValidUsers

do

Num=`find $DIR -user $UserName | wc -l`             
//统计每个用户拥有的文件数

if
[ $Num -gt $LMT ] ; then

echo
"$UserName have $Num files."

fi

done

sh chkfileown.sh

root have
20998
files

4、使用while循环语句

在 Shell脚本中使用while循环语句时,将可以根据 特定的条件重复执行一个命令列表,直到该条件不再满足时为至。除非有特别需要,否则在脚本程序中应该是避免出现无限循环执行命令的情况,因为若无法跳出循 环的话,后边的某些操作将无法执行。为了控制循环次数,通常会在执行的命令序列中包含修改测试条件的语句,当循环达到一定次数后,测试将不再成立,从而可 以结束循环。

while语句的结构:

while 条件测试命令

do

命令序列

done

在 上述语句中,首先通过while判断条件测试命令的返回状态值是否为0(条件成立),如果是,则执行do后边的命令序列,然后返回到while再次进行条 件测试并判断返回状态值,如果条件仍然成立,则继续执行do后边的命令序列,然后返回到while重复条件测试......如此循环,直到所测试的条件不 成立时,跳转到done语句,表示结束循环。

使用while循环语句时,有两个特殊的条件测试返回值,即“true” (真)、"false"(假)。使用“true”作为测试条件时,条件将永远成立,循环体内的语句将无限次执行下去,反之使用“false”则条件永远不 成立,循环体内的语句将不会被执行,这两个特殊值也可以用在if语句的条件测试中。

while语句应用示例:

while语句可以用于需要重复操作的循环系统管理任务,并能够通过设置循环条件来灵活的实现各种管理任务。

eg:由用户从键盘输入一个大于1的整数(如50),并计算从1到该数之间各整数的和。


1

2

3

4

5

6

7

8

9

10

11

12

13

14


[root@localhost ~]# vim sumint.sh

#!/bin/bash

read -p
"Input a number (>1):"
UP

i=
1

Sum=
0

while
[ $i -le $UP ]

do

Sum=`expr $Sum + $i`

i=`expr $i +
1
`

done

echo
"The sum of 1-$UP is : $Sum"

[root@localhost ~]# sh sumint.sh

Input a number (>
1
):
50

The sum of
1
-
50
is
:
1275

eg:批量添加20个系统用户账号,用户名称依次为“stu1”、"stu2"、“stu3”、.......“stu20”,各用户的初始密码均设置为“123456”。


1

2

3

4

5

6

7

8

9


[[email protected] ~]# vim add20users.sh

#!/bin/bash

i=
1

while
[ $i -le
20
]

do

useradd stu$i

echo
"123456"
| passwd --stdin stu$i &> /dev/
null

i=`expr $i +
1
`

done

sh add20users.sh

eg:编写一个批量删除用户的脚本程序,将上面添加的20个用户删除。


1

2

3

4

5

6

7

8


[[email protected] ~]# vim del20users.sh

#!/bin/bash

i=
1

while
[ $i -le
20
]

do

userdel -r stu$i

i=`expr $i +
1
`

done

再次查看: cat /etc/passwd 就会发现那些用户不再存在。

说了if、for 、while、语句后,就可以编写一般的系统管理任务脚本了,记得多多练习!其实除了这些Shell脚本语句外,还有好多好多,如:

case分支语句,until循环、shift移位,以及break和continue循环中断语句。大家可以查询!后续有时间我也会推出~

时间: 2024-10-08 10:40:20

linux之shell脚本管理(一)的相关文章

linux学习—shell脚本知识点总结

Shell脚本 --Shell脚本有点像早期的批处理文件,将一些命令汇总起来一次执行,但Shell有更强大的功能,可以类似于程序的编写,不需要编译就能执行,使用起来很方便,可以简化我们日常的管理工作. 目录 什么是Shell 脚本的运行方法 #!(读shabang)的作用详解 结合案例分析变量类型 特殊变量及其[email protected] $*的区别 退出状态 算数运算 test和[ expression ]判断 一.什么是Shell 我们知道管理整个计算机硬件的其实是核心(kernel)

linux下shell脚本执行方法及exec和source命令

exec和source都属于bash内部命令(builtins commands),在bash下输入man exec或man source可以查看所有的内部命令信息. bash shell的命令分为两类:外部命令和内部命令.外部命令是通过系统调用或独立的程序实现的,如sed.awk等等.内部命令是由特殊的文件格式(.def)所实现,如cd.history.exec等等. 在说明exe和source的区别之前,先说明一下fork的概念. fork是linux的系统调用,用来创建子进程(child

Linux系统shell脚本编程——生产实战案例

Linux系统shell脚本编程--生产实战案例     在日常的生产环境中,可能会遇到需要批量检查内网目前在线的主机IP地址有哪些,还可能需要检查这些在线的主机哪些端口是开放状态,因此依靠手工来检查是可以实现,但比较费时费力,所以需要结合shell脚本来实现批量检查的功能,那么今天就来做个小小的实验. 1.开发脚本前准备 一般大家都知道,测试主机是否在线,常用的命令无非就是ping.nmap,因此,首先找一个地址来测试下ping命令的效果 [[email protected] scripts]

Linux/Unix shell 脚本中调用SQL,RMAN脚本

Linux/Unix shell脚本中调用或执行SQL,RMAN 等为自动化作业以及多次反复执行提供了极大的便利,因此通过Linux/Unix shell来完成Oracle的相关工作,也是DBA必不可少的技能之一.本文针对Linux/Unix shell脚本调用sql, rman 脚本给出了相关示例. 一.由shell脚本调用sql,rman脚本 [python] view plain copy print? 1.shell脚本调用sql脚本 #首先编辑sql文件 [email protecte

linux:shell脚本的一些语法

读取文件的第一行并赋值给变量 var=`head -1 filename` #`不是单引号,是Esc下方的一个按键,为命令替换符,将命令行执行结果赋给var 读取文件的第N行并赋值给变量 var=`sed -n Np filename` #把N替换成数字 逐行读取文件 while read line do echo $line done < filename linux:shell脚本的一些语法,布布扣,bubuko.com

Linux下Shell脚本输出带颜色文字

Linux下Shell脚本输出带颜色文字 文本终端的颜色可以使用"ANSI非常规字符序列"来生成. 举例:    "echo -e \033[44;37;5m BLUE \033[0m" "echo -e \033[44;37;5m BLUE \033[0m BLACK" 需要修改的地方是红色带下划线的部分,其中[***m部分的内容换成下面的数字,后面的内容是自己想要上色的内容. 以上命令设置作用如下:背景色为蓝色,前景色为白色,字体闪烁,输出字

Linux常用Shell脚本

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

linux 之shell脚本练习

一. #!/bin/bash#自动添加用户,并使初始密码为用户账户名,且用户登录时强制其更改密码i=1while [ $i -le 15 ]do if [ $i -le 9 ]  then  useradd user0$i  echo "user0$i" | passwd --stdin user0$i &> /dev/null  chage -d 0 user0$i else  useradd user$i  echo "user$i" | pass

详解Linux交互式shell脚本中创建对话框实例教程_linux服务器

本教程我们通过实现来讲讲Linux交互式shell脚本中创建各种各样对话框,对话框在Linux中可以友好的提示操作者,感兴趣的朋友可以参考学习一下. 当你在终端环境下安装新的软件时,你可以经常看到信息对话框弹出,需要你的输入.对话框的类型有密码箱,检查表,菜单,等等.他们可以引导你以一种直观的方式输入必要的信息,使用这样的用户友好的对话框的好处是显而易见的.如下图所示: 当你写一个交互式shell脚本,你可以使用这样的对话框来接受用户的输入.whiptail可以在shell脚本中创建基于终端的对