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

shell学习二十七天----退出状态和if语句

2015-06-26 09:33 441 查看
退出状态

每一条命令;不管是内置的,shell函数,还是外部的,当它退出时,都会返回一个小的整数值给引用它的程序,这就是大家所熟知的程序的退出状态.在shell下执行进程是,有很多方式可取用程序的退出状态.

以管理来说,退出状态为0表示”成功”,也就是,程序执行完成且为遭遇到任何问题.其他任何的退出退出状态都为失败.内置变量?(使用命令echo $?)查看上一条命令的退出状态.

案例:当你输入ls -l /dev/null时.

输出:crw-rw-rw- 1 root root 1, 3 6月 25 15:41 /dev/null

接着使用命令:echo $?

输出为0

接着使用命令:ls foo

输出:ls: 无法访问foo: 没有那个文件或目录

echo $?

输出:2

表示没有成功的执行.

POSIX的结束状态





意义

0

命令成功地退出

>0

在重定向或单词展开期间(~,变量,命令,算数展开,以及单词切割)失败

1-125

命令不成功的退出.特定的退出值的含义,是由各个单独的命令定义的.

126

命令找到了,但文件无法执行

127

命令没找到

>128

命令因受到信号而死亡

POSIX留下退出状态128未定义,仅要求他表示某种失败.因为只有低位的8个位会返回给父进程,所以大于255的退出状态都会替换成该值除以256之后的余数.

在shell脚本可以使用exit命令传递一个退出之给踏的调用者.只要将一个数字传递给它,作为一个参数即可.脚本会立即退出,并且调用者会受到该数字且作为脚本的退出值.

说白了exit就是退出当前的shell,在shell脚本中可以终止当前脚本执行.

exit

语法:

exit [exit-value]

用途:

目的是从shell脚本返回一个退出状态给脚本的调用者.

主要选项:



行为模式:

如果没有提供,则以最后一个执行命令的退出状态作为默认的退出状态.如果这就是你要的,则最好明白的在shell脚本里这么写:exit $?

案例:exit

输出为logout,表示退出当前shell

案例二:脚本代码cd $(dirname $0) || exit 1

进入脚本所在目录,否则退出

案例三:脚本中判断参数数量,不匹配就打印使用方式,退出

代码:

if [ "$#" -ne "2" ]; then

echo "usage: $0 <area> <hours>"

exit 2

fi

案例四:在脚本里,退出时删除临时文件

代码:trap “入门-rf tempfile;echo Bye.” exit

案例五:检查上一行的退出码

代码:

EXCODE=$?

if [ "$EXCODE" == "0" ]; then

echo "O.K"

fi



if-elif-else-fi语句

if语法:

1、单分支的if语句

if 条件测试命令

then

命令序列

fi

2、双分支的if语句

if 条件测试命令

then

命令序列1

else

命令序列2

fi

3、多分支的if语句(elif 可以嵌套多个,一般多了用case表达)

if 条件测试命令1

then

命令序列1

elif 条件测试命令2

then

命令序列2

.........

else

命令序列n

fi







if pipeline

[pipeline...]

then

statement-if-true-1

elif pipeline

[pipeline...]

then

statement-iftrue2

else

statement-if-all-else-fails

if

使用方括号作为开始与结束的关键字将语句组织起来.



案例1:

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

bash代码:

#!/bin/bash

read -p "what is your backup directoy : " BakDir

if [ -d $BakDir ];then

echo "$BakDir alerdy exist"

else

echo "$BakDir is not exist,will make it"

mkdir $BakDir

fi





案例2:统计当前登录到系统中的用户数量,若判断是否超过三个,若是则显示实际数量并给出警告信息,否则列出

登录的用户账户名称及所在终端

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



注意:

1、if 与[ 之间必须有空格

2、[ ]与判断条件之间也必须有空格

3、]与; 之间不能有空格





逻辑的not,and与or

“如果john不在家,则...” ,在shell下这种情况的做法是:将惊叹号放在管道前:

if ! grep pattern myfile > /dev/null

then

模式不在这里

fi



“如果john在家,且他不忙,则....”,使用逻辑and.

if grep pattern1 myfile && grep pattern2 myfile

then

myfile包含两种模式

fi



相对的,||运算符则用来测试两个条件中是否有一个为真.:

if grep pattern1 myfile || grep pattern2 myfile

then

myfile包含两种模式之一

fi



逻辑and和or都是快捷运算符,即当判断出整个语句块的真伪时,shell会立即停止执行命令.举例来说,在command1&&command2下,如果aommand1失败,则整个结果不可能为真,所以command2也不会被执行;以此类推,command1||command2指的是:如果command1成功,那么也没有理由执行command2.

不要尝试过度”简练”未使用&&和||来取代if语句.我们不反对简短且简单的事情,例如:

命令:who | grep root > /dev/null && echo root is login on root is login on

输出:root is login on

分析:上面的命令实际做法是:执行who | grep...且如果成功,就显示信息.而我们曾见过厂商提供shell脚本,所使用的是这样的结构:

some_command &&{

one command

a decond command

and a third command

}

这个命令的意思是说将所有的语句块放在一块,只有在some_command成功时他们才被执行.使用if可以让他更简洁:

if some_command

then

one command

a second command

and a third command

fi

最后在判断语句中常用的运算符:

1、字符串判断

str1 = str2      当两个串有相同内容、长度时为真

str1 != str2      当串str1和str2不等时为真

-n str1        当串的长度大于0时为真(串非空)

-z str1        当串的长度为0时为真(空串)

str1 当串str1为非空时为真

2、数字的判断

int1 -eq int2    两数相等为真

int1 -ne int2    两数不等为真

int1 -gt int2int1大于int2为真

int1 -ge int2int1大于等于int2为真

int1 -lt int2int1小于int2为真

int1 -le int2int1小于等于int2为真

3 文件的判断

-r file     用户可读为真

-w file     用户可写为真

-x file     用户可执行为真

-f file     文件为正规文件为真

-d file     文件为目录为真

-c file     文件为字符特殊文件为真

-b file     文件为块特殊文件为真

-s file     文件大小非0时为真

-t file     当文件描述符(默认为1)指定的设备为终端时为真

3、复杂逻辑判断

-a         与

-o        或

!        非



test命令

test命令可以处理shell脚本里的各类工作.它产生的不是一般输出,而是可使用的退出状态.test接受各种不同的参数,可控制它要执行哪一种测试.



test命令有另一种形式:[...],这种永福的作用完全与test命令一样.因此,下面这两个案例表达的意思相同

if test “$str1”=”$str2”

then

...

fi



if [ “$str1” = “$str2” ]

then

...

fi

一样



test的语法:

test [expression]

[ [expression] ]

用途:

为了测试shell脚本里的条件,通过退出状态返回其结果.要特别注意的是:这个命令的第二种形式,方括号根据字面意义逐字的输入,且必须与括起来的expression以空白隔开.

主要选项:

和使用用于if的选项一致.

其中



选项

含义

string

如果...则为真

-b file

file是块设备文件

-d file

file是目录

-c file

file是字符设备文件

-e file

file存在

-f file

file为一般文件

-g file

file有设置他的setgid位

-h file

file是一符号链接

-L file

file是一符号链接(等同于 -h)

-n string

string是非null

-p file

file是一命名的管道(FIGO文件)

-r file

file是可读的

-S file

file是socket

-s file

file不是空的

-t n

文件描述符n指向一终端

-u file

file有设置它的setuid位

-w file

file是可写入的

-x file

file是可执行的,或file是可被查找的目录

-z string

string为null

s1=s2 或者s1!=s2

字符串相不相等

n1 -eq n2

整数n1等于n2

n1 -ne n2

整数n1不等于n2

n1 -lt n2

n1小于n2

n1 -gt n2

n1大于n2

n1 -le n2

n1小于或等于n2

n1 -ge n2

n1大于或等于n2

案例:

bash代码;

#!/bin/bash

cd /bin

if test -e ./bash //其实这里相当于if [ -e ./bahs ]

then

echo 'the file already exist!'

else

echo 'the file not exist!'

fi

输出结果为:the file already exist!



另外,shell还提供了-a(逻辑AND),-o(逻辑OR),-a的优先级高于-o,而=与!=优先级则高于其他的二元运算符.

注意:在使用-a和-o(这两个事test运算符)与&&和||(这两个事shell运算符)之间有一个差异:

if [ -n “$str” -a -f “$file” ] 一个test命令,两种条件

if [-n “str”] && [ -f “$file” ] 两个命令,一块接方式计算

if [-n “$str” && -f ”$file”] 语法错误

第一个案例,test会计算两种条件.而第二个案例,shell执行第一个test命令,且只有在第一个命令是成功的情况下,才会执行第二个命令.最后一个案例,&&为shell运算符,所以它会终止第一个test命令,然后这个命令会抱怨它找不到结束的]字符,且以失败的值退出.即使test可以成功的退出,接下来的检查还会失败,因为shell(最有可能)找不到一个名为-f的命令





精简表达式:

使用命令:[1 eq1 ] &&echo’OK’

输出:ok

使用命令:[ 2 < 1 ] &&echo ‘OK’

输出:-bash: 1: No such file or directory

使用命令:[ 2 \< 1 ] &&echo ‘OK’这样就可以了

使用命令:[ 2 -gt 1 -a 3 -lt 4 ]&&echo 'Ok'

输出:Ok

使用命令:[ 2 -gt 1 && 3 -lt 4 ]&&echo 'Ok'

输出:-bash: [: missing `]'

注意:在[] 表达式中,常见的>,<需要加转义字符,表示字符串大小比较,以acill码位置作为比较。不直接支持<>运算符,还有逻辑运算符 || 和 && 它需要用-a[and] –o[or]表示。

刚才使用的[],现在再来看使用[[]]

案例:

使用命令:[[ 2 < 3 ]]&&echo ‘OK’

输出OK.

使用命令:[[ 2 < 3 && 4 < 5 ]] && echo 'ok'

输出:ok

注意:[[]] 运算符只是[]运算符的扩充。能够支持<,>符号运算不需要转义符,它还是以字符串比较大小。里面支持逻辑运算符 || 和 &&

bash 的条件表达式中有三个几乎等效的符号和命令:test,[]和[[]]。通常,大家习惯用if [];then这样的形式。而[[]]的出现,根据ABS所说,是为了兼容><之类的运算符。

不考虑对低版本bash和对sh的兼容的情况下,用[[]]是兼容性强,而且性能比较快,在做条件运算时候,可以使用该运算符。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: