Chinaunix首页 | 论坛 | 博客
  • 博客访问: 871871
  • 博文数量: 72
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1693
  • 用 户 组: 普通用户
  • 注册时间: 2014-08-04 15:53
个人简介

主要从事Linux,云原生架构改造,服务网格,ELK,python,golang等相关技术。

文章分类

全部博文(72)

文章存档

2015年(52)

2014年(20)

分类: LINUX

2015-05-09 14:20:15

1.变量的处理计算变量长度与其他不同方法的耗时对比

[root@server2 ~]# chars=`seq -s "" 100`2015-1-22

[root@server2 ~]# echo ${#chars}

291

[root@server2 ~]# echo $(expr length "$chars")

291

[root@server2 ~]# echo ${chars} | wc -m

292

[root@server2 ~]# time for i in $(seq 11111);do count=${#chars};done;

real 0m2.446s

user 0m2.415s

sys

0m0.028s

[root@server2 ~]# time for i in $(seq 11111);do count=${chars} | wc -m ;done;

real 1m0.134s

user 0m13.734s

sys

0m23.029s

[root@server2 ~]# time for i in $(seq 11111);do count=`echo expr length "${chars}"`;done;

real 0m18.653s

user 0m7.708s

sys

0m8.562s

我们看到速度相差几十到上百倍,一般情况调用外部命令处理,与内置功能操作性能相差较

大。在 shell 编程中我们应尽量使用内置操作或函数完成。

变量处理替换的一些参考资料

01)man bash 变量处理大全

02)http://www.cnblogs.com/chengmo/archive/2010/10/02/1841355.html

[root@server2 ~]# man bash 进入后查找 word,我们一直往下翻就可以看到对字符的各种处

注:我们要想成为比较好的,我们就要看官方的一首资料,但是如果实在不行,我们可以去

网上搜集二手的资料,比如别人总结好的资料

2.变量的数值计算

变量的数值计算常见的有如下几种命令:

(())、let、expr、bc $[]

1) (())用法:(此法很常用,且效率高)

用于执行简单的整数运算,只需将特定的算术表达式用"$(("和"))"括起来

shell 的算术运算符号都置于"$(("..."))"的语法中。这一语法如同双引号功能,除了内嵌双引号

无需转义。

范例 1:shell 的算术运算实例如下:

[root@server2 ~]# ((a=1+2**3-4%3))

[root@server2 ~]# echo $a

8

[root@server2 ~]# b=$((1+2**3-4%3))

//两个**为幂运算

[root@server2 ~]# echo $b

8

[root@server2 ~]# echo $((1+2**3-4%3))

8

[root@server2 ~]# echo $((a+=1))

9

[root@server2 ~]# echo $((a++))

9

[root@server2 ~]# echo $a

10

[root@server2 ~]# echo $((a--))

10

[root@server2 ~]# echo $a

9

[root@server2 ~]# echo $((--a))

8

[root@server2 ~]# echo $((3>2))

1

[root@server2 ~]# echo $((3<2))

0

[root@server2 ~]# echo $((100*(100+1)/2))

5050

注意:

a.上面涉及到的变量必须是整数,不能是小数或者是字符串。

b.bc 命令可以进行浮点数运算,但一般较少用到,下面会讲到。提示:你可以直接在

shell 脚本中使用上述命令进行计算。

范例 3:

[root@server2 ~]# myvar=99

[root@server2 ~]# echo $(($myvar + 1))

100

[root@server2 ~]# echo $(( $myvar + 1 ))

//(()

)两边有几个空格不敏感,也可以没有

100

[root@server2 ~]# myvar=$(( $myvar + 1))

//还可以赋值给变量然后输出变量

[root@server2 ~]# echo $myvar

100

范例 4:各种(())的计算命令行执行例子

[root@server2 ~]# echo $(( 100/5 ))

20

[root@server2 ~]# echo $(( 100 + 5 ))

105

[root@server2 ~]# echo $(( 100 - 5 ))

95

[root@server2 ~]# echo $(( 100 * 5 ))

500

[root@server2 ~]# echo $(( 100 ** 5 ))

//幂

10000000000

[root@server2 ~]# echo $(( 100 %5 ))

0

范例 5:各种(())运算的 shell 脚本例子

[root@server2 ~]#cat test.sh

#!/bin/bash

a=6

b=2

echo "a-b=$(( $a - $b ))"

echo "a+b=$(( $a + $b ))"

echo "a*b=$(( $a * $b ))"

echo "a/b=$(( $a / $b ))"

echo "a**b=$(( $a ** $b ))"

echo "a%b=$(( $a %$b ))"

[root@server2 ~]#sh test.sh

a-b=4

a+b=8

a*b=12

a/b=3

a**b=36

a%b=0

[root@server2 ~]#cat test.sh

#!/bin/bash

a=$1

b=$2

echo "a-b=$(( $a - $b ))"

echo "a+b=$(( $a + $b ))"

echo "a*b=$(( $a * $b ))"

echo "a/b=$(( $a / $b ))"

echo "a**b=$(( $a ** $b ))"

echo "a%b=$(( $a %$b ))"

[root@server2 ~]#sh test.sh 6 2

a-b=4

a+b=8

a*b=12

a/b=3

a**b=36

a%b=0

[root@server2 ~]#cat jisuan.sh

//一个四则运算器

#!/bin/bash

#add,subtract,multiply and divide by yubing 2013-07-13

print_usage(){

printf "Please enter an integer \n"

}

for i in $(seq 100)

{

read -p "Please input first number:" firstnum

if [ -n "`echo $firstnum | sed 's/[0-9]//g'|sed 's/-//g'`" ];then

    print_usage;

    continue;

fi

break;

}


for i in $(seq 100)

{

read -p "Please input the opertors:" operators

if [ "${operators}" != "+" ]&&[ "${operators}" != "*" ]&&[ "${operators}" != "/" ];then

    echo "please use + - * /"

    continue;

fi

break;
}
for i in $(seq 100)
{
read -p "Please input second number:" secondnum
if [ -n "`echo $secondnum | sed 's/[0-9]//g'|sed 's/-//g'`" ];then
    print_usage;
    continue;
fi
break;
}
echo "${firstnum}${operators}${secondnum}=$((${firstnum}${operators}${secondnum}))"

[root@server2 ~]# sh jisuan.sh

Please input first number:3

Please input the opertors:*

Please input second number:2

3*2=6

网友的例子:

http://zhangbo.blog.51cto.com/350645/1172900

http://blog.163.com/shaohj_1999@126/blog/static/634068512011388619129/


2)let 命令的用法

格式:

let 赋值表达式

注:let 赋值表达式功能等同于:(

(赋值表达式))

范例 1:给自变量 i 加 8

[root@server2 ~]# i=2

[root@server2 ~]# let i=i+8

[root@server2 ~]# echo $i

10

[root@server2 ~]# i=i+8

//去掉 let 定义

[root@server2 ~]# echo $i

i+8

输出的结果

提示:let i=i+8 等同于((i=i+8)

),但后者效率更高

范例 2:利用 let 计数监控 web 服务状态

#监控服务状态

ServerMonitor(){

#服务状态监控

timeout=10

fails=0

success=0

while true

do

/usr/bin/wget --timeout=$timeout --tries=1 http://192.168.2.2/ -q -o /dev/null

if [ $? -ne 0 ]

then

let fails=fails+1

success=0

else

fails=0

let success=1

fi

if [ $success -ge 1 ]

then

exit 0;

fi

if [ $fails -ge 2 ]

then

Critical=”TMS 应用服务出现故障,紧急处理!”

echo $Critical | mutt -s “服务 down” yhai_ying@163.com

exit

fi

done

}

3)expr (evaluate expressions)命令的用法:

expr 命令一般用于整数值,但也可用于字符串,用来求表达式变量的值,同时 expr

也是一个手工命令行计算器

语法:expr Expression

[root@server2 ~]# expr 2+2

2+2

[root@server2 ~]# expr 2 + 2

4

[root@server2 ~]# expr 2 - 2

0

[root@server2 ~]# expr 2 * 2

expr: 语法错误

[root@server2 ~]# expr 2 \* 2

//其中*号用/来转义

4

[root@server2 ~]# echo $(expr length "we are hy.")

10

提示:

1)注意运算符左右都有空格

2)使用乘号时,反斜线屏蔽其特定含义。因为 shell 可能会误解星号的含义

增量计算

Expr 在循环中可用于增量计算。首先,循环初始化为 0,然后循环值加 1,反引号

的用法为命令替代。最基本的一种是从(expr)命令接受输出并将之放入循环变量。

例:给自变量 i 加 1

[root@server2 ~]# i=0

[root@server2 ~]# i=`expr $i + 1`

//这样计算的效率很低

[root@server2 ~]# echo $i

1

expr $[$a+$b]表达式形式,其中$a$b 可为整数值

[root@server2 ~]# expr $[2+3]

5

[root@server2 ~]# expr $[2*3]

6

[root@server2 ~]# expr $[2**3]

8

[root@server2 ~]# expr $[2/3]

0

[root@server2 ~]# expr $[2%3]

2

[root@server2 ~]# a=5

[root@server2 ~]# b=6

[root@server2 ~]# expr $[$a+$b]

11

expr 将其后的串解释为表达式并计算其值,运算符前后需有空格

其他特殊用法:

expr 用法 ssh-copy-id 脚本

[root@hy ~]# vim /usr/bin/ssh-copy-id

ID_FILE="${HOME}/.ssh/id_rsa.pub"

if [ "-i" = "$1" ]; then

shift

# check if we have 2 parameters left, if so the first is the new ID

file

if [ -n "$2" ]; then

if expr "$1" : ".*\.pub" > /dev/null ; then

ID_FILE="$1"

else

ID_FILE="$1.pub"

fi

shift

# and this should leave $1 as the target name

其中:expr "$1" : ".*\.pub" 匹配*.pub 格式的文件如果是则为真非零,如果为假则

输出 0

[root@server2 ~]# expr "test.txt" : ".*\.pub"

0

[root@server2 ~]# expr "test.pub" : ".*\.pub"

8

这里显示的是 test.pub 这个字符串的长度

判断文件或字符串的扩展名小案例:

[root@server2 ~]# expr "test.txt" : ".*\.pub" && echo 1 || echo 0

0

0

[root@server2 ~]# expr "test.pub" : ".*\.pub" && echo 1 || echo 0

8

1

通过 expr 判断变量是否为整数

[root@server2 ~]# vim expr.sh

#!/bin/bash

while true

do

read -p "Pls input:" a

expr $a + 0 &>/dev/null

//expr $a + 0 >/dev/null 2>&1

[ $? -eq 0 ] && echo int || echo chars

done

[root@server2 ~]# sh expr.sh

Pls input:a

chars

Pls input:8.21

chars

Pls input:2

Int

通过 expr 计算字符串的长度

[root@server2 ~]# chars=`seq -s "" 100`

[root@server2 ~]# echo ${#chars}

291

[root@server2 ~]# echo $(expr length "$chars")

291

4)bc 命令的用法:

bc 是 UNIX 下的计算器,它也可以用在命令行下面:

例:

[root@server2 ~]# i=2

[root@server2 ~]# echo $i+1

2+1

[root@server2 ~]# echo $i+1 | bc

3

//可以计算,但是效率比较低

*因为 bc 支持科学计算,所以这种方法功能非常强大

[root@server2 ~]# echo 3.5+5 |bc

8.5

[root@server2 ~]# echo 3.5+5.6 |bc

9.1

[root@server2 ~]# echo 3.5-3.1 |bc

.4

通过计算表达式计算

[root@server2 ~]# seq -s "+" 10

1+2+3+4+5+6+7+8+9+10

[root@server2 ~]# seq -s "+" 10 |bc

55

[root@server2 ~]# echo "scale=2;5.23 / 3.13" |bc

//这样表示保留两位小数

1.67

[root@server2 ~]# echo "obase=2;8"|bc

//这样表示进制转换

1000

[root@server2 ~]# echo "obase=16;32" |bc

20

特点:bc 的特点是支持小数运算

5)typeset 命令的用法:

[root@server2 ~]# typeset -i A=1 B=3

[root@server2 ~]# A=A+B

//效率高

[root@server2 ~]# echo $A

4

6)$[]的用法:

[root@server2 ~]# echo $[2+3]

5

[root@server2 ~]# echo $[ 2 + 3 ]

5

[root@server2 ~]# echo $[2-3]

-1

[root@server2 ~]# echo $[2*3]

6

[root@server2 ~]# echo $[2/3]

0

[root@server2 ~]# echo $[2%3]

2

实际解决问题例子:打印数学杨辉三角(第一种为重点)

http://oldboy.blog.51cto.com/2561410/756234

#!/bin/bash

if(test -z $1);then

======================================================================

3.shell 变量的输入

Shell 变量除了可以直接赋值或脚本传参外,还可以使用 read 命令从标准输入获得

『语法格式』

read 『参数』『变量名』

『常用参数』

-p prompt:设置提示信息

-t timeout:设置输入等待的时间,单位默认为秒。

范例 1:read 的基本读入

[root@server2 ~]# read -p "please input a number:" a //指定提示符

please input a number:3

[root@server2 ~]# read -t 3 -p "please input a number:" a //指定自动退出时间

please input a number:[root@server2 ~]#

[root@server2 ~]# read -t 5 -p "please input a number:" a b

//可连续接收多个值

please input a number:33 44

[root@server2 ~]# echo $a $b

33 44

提示:上面 read -p 的功能可以用 echo 和 read 实现

echo -n “please input two number:”

read a1 a2

以上两句和下面的命令相当(-t 排除在外)

例:实现简单的计算器功能

read.sh

#!/bin/bash

#read -p "please input two numbers:" a b

echo -n "please input two numbers:"

read a b

echo "a+b = $(( $a + $b ))"

echo "a-b = $(( $a - $b ))"

echo "a*b = $(( $a * $b ))"

echo "a/b = $(( $a / $b ))"

echo "a**b = $(( $a ** $b ))"

echo "a%b = $(( $a %$b ))"

如何用循环判断输入的数不是整数,并且重新输入:

方法一:

#!/bin/bash

$a

$b

function_input(){

read -p "Pls input:" c

for i in $(seq 10)

do

expr $c + 0 &>/dev/null

[ $? -eq 0 ] && break || read -p "please reinput:" c

done

}

function_input;

a=$c

function_input;

b=$c

echo "a+b = $(( $a + $b ))"

echo "a-b = $(( $a - $b ))"

echo "a*b = $(( $a * $b ))"

echo "a/b = $(( $a / $b ))"

echo "a**b = $(( $a ** $b ))"

echo "a%b = $(( $a %$b ))"

方法二:

#!/bin/bash

$a

$b

function_input(){

read -p "Pls input:" c

while true

do

expr $c + 0 &>/dev/null

[ $? -eq 0 ] && break || read -p "please reinput:" c

done

}

function_input;

a=$c

function_input;

b=$c

echo "a+b = $(( $a + $b ))"

echo "a-b = $(( $a - $b ))"

echo "a*b = $(( $a * $b ))"

echo "a/b = $(( $a / $b ))"

echo "a**b = $(( $a ** $b ))"

echo "a%b = $(( $a %$b ))"

======================================================================

4.条件测试

1)测试语句

1.1)条件测试语法

在 bash 的各种流程控制结构中通常要进行各种测试,然后根据测试结果执行不同

的操作,有时也会通过与 if 等条件语句相结合,让我们可以方便的完成判断。

生活中的例子:我要去图书馆,问一下

『语法说明』

格式 1:test<测试表达式>

格式 2:[<测试表达式>]

格式 3:[[<测试表达式>]]

说明:

格式 1 和格式 2 是等价的。

格式 3 为扩展的 test 命令,有网友推荐用格式 3,老男孩习惯用格式 2.

提示:

在[[]]中可以使用通配符。&&、||、>、<等操作符可以应用于[[]]中,但不能应用于

[]中。

对整数进行关系运算,也可以使用 shell 的算术运算符(()).

『语法例子』

格式 1: test<测试表达式>

范例 1:test 测试文件

[root@server2 ~]# test -f file && echo true || echo false

false

[root@server2 ~]# touch file

[root@server2 ~]# test -f file && echo true || echo false

true

范例 2:test 命令非(!)的写法

[root@server2 ~]# test ! -f file && echo true || echo false

true

[root@server2 ~]# touch file

[root@server2 ~]# test ! -f file && echo true || echo false

false

格式 2:[<测试表达式>]

范例:[]

[root@server2 ~]# rm -f file

[root@server2 ~]# [ -f file ] && echo true|| echo false

false

[root@server2 ~]# touch file

[root@server2 ~]# [ -f file ] && echo true|| echo false

true

[root@server2 ~]# [ -f file ] && cat file

[root@server2 ~]# vim file

[root@server2 ~]# [ -f file ] && cat file

hello

格式 3:[[<测试表达式>]]

范例:[[]]

[root@server2 ~]# [[ -f file && -d dir ]] && echo 1 || echo 0

0

[root@server2 ~]# [ -f file && -d dir ] && echo 1 || echo 0

-bash: [: missing `]'

0

[root@server2 ~]# [ -f file -a -d dir ] && echo 1 || echo 0 //在使用[]的时候-a 代替了

&&表示 and

0

[root@server2 ~]# touch file;touch dir

[root@server2 ~]# [ -f file -a -d dir ] && echo 1 || echo 0

0

[root@server2 ~]# touch file;mkdir dir

[root@server2 ~]# [[ -f file && -d dir ]] && echo 1||echo 0

1

[root@server2 ~]# [ -f file -a -d dir ] && echo 1 || echo 0

1

注:和-a 相对的是-o,和&&相对的是||

1.2)文件测试操作符

在书写测试表达式时,可以使用下表中的文件测试操作符

常用文件测试操作符号

常用文件测试操作符号的记忆方法:

[root@server2 ~]# echo f=file

f=file

[root@server2 ~]# echo d=directory

d=directory

[root@server2 ~]# echo s=exist

s=exist

[root@server2 ~]# echo r=read

r=read

[root@server2 ~]# echo w=write

w=write

[root@server2 ~]# echo x=executable

x=executable

[root@server2 ~]# echo nt="newer than"

nt=newer than

[root@server2 ~]# echo ot="older than"

ot=older than

1.3)字符串测试操作符

字符串测试操作符的作用:比较两个字符串是否相同、字符串长度是否为零,

字符串是否为 NULL(注:bash 区分零长度字符串和空字符串)等。

“=”比较两个字符串是否相同,与==等价,如 if[ “$a” = “$b” ],其中$a 这样的

变量最好用“”括起来,因为如果中间有空格、*等符号就可能出错了,当然更好的

方法就是[ “${a}” = “${b}” ]。“!=”比较两个字符串是否相同,不同则为“是”。

字符串测试操作符

字符串测试操作符提示:

1)-n 比较字符串长度是否不为零,如果不为零则为真,如:[ -n “myvar” ]

2)-z 比较字符串长度是否等于零,如果等于零则为真,如:[ -z “myvar” ]

1.4)整数二元比较操作符

在书写测试表达式时,可以使用下表中的整数二元比较操作符

整数二元比较操作符

提示:

1)“<”符号意思是小于,if[[ “$a” < “$b” ]],if[[ “$a” \< “$b” ]]。在单[]中需要转

义,因为 shell 也用<和>重定向

2)“>”符号意思是大于,if[[ “$a” > “$b” ]],if[[ “$a” \> “$b” ]]。在单[]中需要转

义,因为 shell 也用<和>重定向

3)“=”符号意思是等于,if[[ “$a” = “$b” ]] if[[ “$a” = “$b” ]] 在[]中不需要转

特别提示:

经过实践,“=”和“!=”在[]中使用不需要转义,包含“>”和“<”的符号在[]中使用

需要转义,对于数字不转义的结果未必会报错,但是结果可能不会对。

范例 1:二元数字比较

[root@server2 ~]# [ 2 > 1 ] && echo 1 || echo 0

1

[root@server2 ~]# [ 2 < 1 ] && echo 1 || echo 0

1

[root@server2 ~]# [ 2 \< 1 ] && echo 1 || echo 0

0

[root@server2 ~]# [ 2 \> 1 ] && echo 1 || echo 0

1

[root@server2 ~]# [ 2 -gt 1 ] && echo 1 || echo 0

1

[root@server2 ~]# [ 2 \> 1 ] && echo 1 || echo 0

1

[root@server2 ~]# [[ 2 < 1 ]] && echo 1 || echo 0

0

[root@server2 ~]# [[ 2 > 1 ]] && echo 1 || echo 0

1

[root@server2 ~]# [[ 2 = 1 ]] && echo 1 || echo 0

0

[root@server2 ~]# [ 2 = 2 ] && echo 1 || echo 0

1

[root@server2 ~]# [ 2 != 2 ] && echo 1 || echo 0

0

提示:经过实践,“=”和“!=”在[]中使用不需要转义也可以

[root@server2 ~]# [[ 2 -lt 1 ]] && echo 1 || echo 0

0

[root@server2 ~]# [[ 2 -gt 1 ]] && echo 1 || echo 0

1

范例 2:二元字符比较

[root@server2 ~]# [ "a" < "bc" ] && echo 1 || echo 0

1

[root@server2 ~]# [ "a" > "bc" ] && echo 1 || echo 0

1

上面两个条件不一样,但结果一样,虽然没报语法错误,但显然不对。

[root@server2 ~]# [ "a" \> "bc" ] && echo 1 || echo 0

0

[root@server2 ~]# [ "a" \< "bc" ] && echo 1 || echo 0

1

1.5)逻辑操作符

在书写测试表达式时,可以使用表中的逻辑操作符实现复杂的条件测试

逻辑链接符

提示:

!中文意思是反:与一个逻辑值相反的逻辑值

-a 中文意思是与(and &&):两个逻辑值都为“真”,返回值才为“真”,反

之为“假”

-o 中文意思是或(or ||):两个逻辑值只要有意各为“真”,返回值就为“真”

2)条件测试举例

下面举一些条件测试的例子。为了清晰的显示测试结果,我们在屏幕上输出 1(表

示真)或 0(表示假)表示测试结果

提示:这和前面的状态变量“$?”返回 0 为真不一样!

[ -f “$file” ] && echo 1 || echo 0

//这是条件表达式的用法

If [ -f “$file” ];then echo 1;else echo 0;fi

提示:

1.以上两条语句的功能是等同的。

2.变量$file 加了双引号,这时编程的好习惯,可以防止很多意外的错误发生

1.1)文件测试举例

首先我们定义 file1 和 file2 两个变量,并的你别赋予两个系统文件路径及文件名的

值。

[root@server2 ~]# file1=/etc/services;file2=/etc/rc.local

[root@server2 ~]# echo $file1 $file2

/etc/services /etc/rc.local

[root@server2 ~]# [ -f "$file1" ] && echo 1 || echo 0

1

[root@server2 ~]# [ -d "$file1" ] && echo 1 || echo 0

0

[root@server2 ~]# [ -f "$file2" ] && echo 1 || echo 0

1

[root@server2 ~]# [ -d "$file2" ] && echo 1 || echo 0

0

[root@server2 ~]# [ -e "$file1" ] && echo 1 || echo 0

1

[root@server2 ~]# [ -e "$file2" ] && echo 1 || echo 0

1

[root@server2 ~]# [ -w "$file1" ] && echo 1 || echo 0

1

//这里我们测试的时候是在 root 用户下,root 用户具有超级权限,因此我

们切换到一个普通用户下测试

[root@server2 ~]# su hy

[hy@server2 root]$ [ -w "$file1" ] && echo 1 || echo 0

0

注意下面的测试,“”号的有无,这里 file7 这个变量没有被定义

[root@server2 ~]# [ -f "$file7" ] && echo 1 || echo 0

0

[root@server2 ~]# [ -f $file7 ] && echo 1 || echo 0

1

可以看一下/etc/init.d/nfs

# Source networking configuration.

[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network

# Check for and source configuration file otherwise set defaults

[ -f /etc/sysconfig/nfs ] && . /etc/sysconfig/nfs

# Remote quota server

[ -z "$RQUOTAD" ] && RQUOTAD=`type -path rpc.rquotad`

范例 4:多文件单中括号[]与或非测试

可用与(-a 和&&)

、或(-o 和||)、非(!)将多个条件表达式连接起来,接着上面

的变量测试。

[root@server2 ~]# file1=/etc/services;file2=/etc/init.d/nfs

[root@server2 ~]# [ -f "$file1" -a -e "$file2" ] && echo 1 || echo 0

0

[root@server2 ~]# [ -f "$file1" -o -e "$file2" ] && echo 1 || echo 0

1

[root@server2 ~]# [ -f "$file1" || "$file2" ] && echo 1 || echo 0

-bash: [: missing `]'

//这种用法是错误的使用下面的用法

-bash: /etc/init.d/nfs: 没有那个文件或目录

0

如果你非要使用单[]加&&或||那就用如下方法:

[root@server2 ~]# [[ -f "$file1" || "$file2" ]] && echo 1 || echo 0

1

[root@server2 ~]# [ -f "$file1" ] || [ -e "$file2" ] && echo 1 || echo 0

1

范例 5:双中括号多条件文件与或非测试

[root@server2 ~]# [[ -f "$file1" && -e "$file2" ]] && echo 1 || echo 0

0

[root@server2 ~]# [[ -f "$file1" -a -e "$file2" ]] && echo 1 || echo 0 //也不能这么用

-bash: syntax error in conditional expression

-bash: syntax error near `-a'

范例 6(生产):系统 bind 启动脚本举例:named(bind dns 服务)

在做测试判断时,不一定非要按照前面的方法。直接用后者做测试判断有时更简洁。

例如:

[root@server2 ~]# [ -f "$file1" ] && echo 1

1

[root@server2 ~]# [[ -f "$file1" && -e "$file2" ]] || echo 0

0

系统范例:/etc.init.d/nfs

[ -x /usr/sbin/rpc.nfsd ] || exit 5

[ -x /usr/sbin/rpc.mountd ] || exit 5

[ -x /usr/sbin/exportfs ] || exit 5

范例 8:学生学习问答案例:判断条件后执行多条命令语句。

[判断] || 命令 1 && 命令 2 && 命令 3,现在是如果前面条件成立了,也会执行命

令 2 和命令 3!

我想让后面的命令都不执行,我们可以用一个{}将后面的命令括起来

就实现了下面的功能:

if [ 条件 ]

then

do someting

else

命令 1

命令 2

命令 3

fi

例如:

[ 3 -ne 3 ] || {

echo “I am oldboy”

echo “I am coming”

exit 1

}

如果写在一行里面,里面的每个命令还需要用分号结尾,如下所示:

[ 3 -ne 3 ] || { echo “I am hy”; echo “I am coming”; exit 1; }

提示:本例的用法很简洁,但是理解起来不如 if 条件句容易,因此,请读者根据

自身情况使用。

拓展:

1)结尾小括号用法:

[ $ERROR -eq 0 ] && “jdk 安装成功!” || ( echo “jdk 安装失败,请检测!” &&

exit 1 )

2)结尾中括号用法:

[ $ERROR -eq 0 ] && “jdk 安装成功!” || [ echo “jdk 安装失败,请检测!” &&

exit 1 ]

3)结尾大括号用法:

[ $ERROR -eq 0 ] && “jdk 安装成功!” || { echo “jdk 安装失败,请检测!” &&

exit 1 }

[ $ERROR -eq 0 ] && “jdk 安装成功!” || {

echo “jdk 安装失败,请检测!”

exit 1

}

1.2)字符串测试举例

[root@server2 ~]# [ -n "$file" ] && echo 1||echo 0

0

//这里-n 指长度不为零

[root@server2 ~]# [ -z "$file" ] && echo 1||echo 0

1

//这里-z 指长度为零

去掉双引号试试:

[root@server2 ~]# [ -z $file ] && echo 1||echo 0

1

[root@server2 ~]# [ -n $file1 ] && echo 1||echo 0

1

特别强调:字符串比较要加双引号。

范例 2(生产):系统脚本/etc/init.d/nfs 字符串测试的应用:

# Remote quota server

[ -z "$RQUOTAD" ] && RQUOTAD=`type -path rpc.rquotad`

[ -z "$MOUNTD_NFS_V2" ] && MOUNTD_NFS_V2=default

[ -z "$MOUNTD_NFS_V3" ] && MOUNTD_NFS_V3=default

# Number of servers to be started by default

[ -z "$RPCNFSDCOUNT" ] && RPCNFSDCOUNT=8

范例 3:多条件字符串测试

[root@hy ~]# [ -z "$file1" -a -n "$file"] && echo 1 || echo 0

0

[root@hy ~]# [ -z "$file1" ] && echo 1 || echo 0

1

[root@hy ~]# [[ -z "$file1" && -n "$file" ]] && echo 1 || echo 0

0

[root@hy ~]# [[ -z "$file1" || -n "$file" ]] && echo 1 || echo 0

1

[root@hy ~]# [ "$file" = "$file" ] && echo 1 || echo 0

1

[root@hy ~]# [ "$file" != "$file"] && echo 1 || echo 0

0

[root@hy ~]# file1=/etc/services

[root@hy ~]# file2=/etc/rc.local

[root@hy ~]# [ "${#file1}" = "${#file2}" ] && echo 1 || echo 0

1

//两边字符串的长度是否相等

[root@hy ~]# [ "${file1}" = "${file2}" ] && echo 1 || echo 0

0

//两边的字符串是否相等

2.3)整数测试举例:

范例 1:整数条件测试举例

[root@server2 ~]# a1=10;a2=13

[root@server2 ~]# [ $a1 -eq $a2 ] && echo 1 || echo 0

0

[root@server2 ~]# [ $a1 -gt $a2 ] && echo 1 || echo 0

0

[root@server2 ~]# [ $a1 -lt $a2 ] && echo 1 || echo 0

1

[root@server2 ~]# [ "$a1" -ge "$a2" ] && echo 1 || echo 0

0

[root@server2 ~]# [ "$a1" -le "$a2" ] && echo 1 || echo 0

1

范例 2:直接通过数学运算符比较

这里不再讲解,另外注意有的运算符需要转义

提示:“=”和“==”也可以用于[]中。

2.4)test 命令测试的用法

范例 1:用 test 命令测试字符串

[root@server2 ~]# test -z "$file1" || echo 0

0

[root@server2 ~]# test -z "$file1" && echo 1|| echo 0

0

[root@server2 ~]# [ -z "$file1" ]&& echo 1|| echo 0

0

[root@server2 ~]# test -n "$file1" && echo 1|| echo 0

1

范例 2:用 test 命令测试真书比较

[root@server2 ~]# test "dd" == "ff" && echo 1 || echo 0

0

[root@server2 ~]# test "dd" == "dd" && echo 1 || echo 0

1

[root@server2 ~]# test "dd" != "dd" && echo 1 || echo 0

0

结论:test 命令测试的功能很强大,但是和[],[[]]之前都是重合的功能,因此,在

实际工作中我们选择一种适合我们自己的语法就 ok 了,其他的语法,别人写的脚本可

以阅读就可以了。

2.5)逻辑操作符的举例

其实前面的内容已经有提到逻辑操作符的使用了。1.5 逻辑操作符也说明了。

范例 1:&&和-a 与逻辑符脚本例子

#!/bin/bash

echo -n "请输入两个数字[格式为:m n]":

read m n

第一种写法:

if [ ${m} -eq 1 ] && [ ${n} -eq 2 ];then

echo "good"

else

echo "bad"

fi

第二中写法:

if [ ${m} -eq 1 -a ${n} -eq 2 ];then

echo "good1"

else

echo "bad1"

fi

第三种写法:

if [[ ${m} -eq 1 && ${n} -eq 2 ]];then

echo "good1"

else

echo "bad1"

fi

范例 2:||和-o 或逻辑符的脚本例子

[root@server2 ~]# [[ -z "$file1" || -z "file2" ]] && echo 1 || echo 0

0

[root@server2 ~]# [[ -z "$file1" || -n "file2" ]] && echo 1 || echo 0

1

[root@server2 ~]# [ -z "$file1" -o -z "file2"] && echo 1 || echo 0

0

范例 3:!非逻辑符的例子

[root@server2 ~]# [ ! -z "$file1" -o -z "file2" ] && echo 1 || echo 0

1

[root@server2 ~]# [[ ! -z "$file1" || ! -z "file2" ]] && echo 1 || echo 0

1

[root@server2 ~]# [[ ! -z "$file1" && ! -z "file2" ]] && echo 1 || echo 0

1

例子:利用 read 和 cat 打印选择菜单

#!/bin/bash

echo "1.[install lamp]"

echo "2.[install lnmp]"

echo "3.[install nfs]"

echo "4.[install rsync]"

read -p "please input then num that you want:" num

case $num in

1)

echo "[install lamp]"

;;

2)

echo "[install lnmp]"

;;

3)

echo "[install nfs]"

;;

4)

echo "[install nfs]"

;;

*)

echo "please reinput:"

esac

第二种写法:

 menu(){

cat <

1.[install lamp]

2.[install lnmp]

3.[install nfs]

4.[install rsync]

please input the num that you want:

END

}

 menu

read a

echo "you selected $a"

第三种写法多级菜单:

menu(){

cat <

1.[install lamp]

2.[install lnmp]

3.[install nfs]

4.[install rsync]

please input the num that you want:

 END

}

menu

read a

[ $a -eq 1 ] && {

cat <

[1.install apache]

[2.install mysql]

[3.install php]

END

}

read b

echo "you want to $b"

http://skyex.blog.51cto.com/5935088/1176453 李灿

写 lamp 的安装脚本

3.if 条件句

1.1if 条件句语法说明

a)单分支结构

if[条件]

then

指令

fi

if[条件];then

指令

fi

多分支结构:

if 条件

then

指令

else

指令

fi

多分支结构:

if 条件

then

指令

elif 条件

then

指令

else

指令

fi

提示:分号相当于命令换行,上面两种语法等同。

特殊写法:if[ -f “$file1” ];then echo 1;fi 相当于:[ -f “$file1” ] && echo 1

范例 1:单分支 if 条件句整数比较大小

两个整数之间的比较:

#!/bin/bash

read a b

if [ $a \> $b ]

//或 if [ $a -gt $b ]

then

echo "max is a=$a"

else

echo "max is b=$b"

fi

两个字符串之间的比较:

例:判断一个文件是否存在,如果不存在,创建它

第一种写法:

#!/bin/bash

read a

if [ "`ls /root/ | grep $a`" == $a ]

then

echo "$a is exist"

else

{

echo "$a is not exist,it will be create by $USER"

touch /$USER/$a

}

fi

第二种写法:

#!/bin/bash

DIR="$USER"

read FILE

if [ -e /$DIR/$FILE ]

then

echo "$FILE is exist"

else

//if [ ! -e /$DIR/$FILE ]

{

echo "$FILE is not exist,it will be create by $USER"

touch /$USER/$FILE

}

fi

第三种写法:

#!/bin/bash

FILEPATH="/server/scripts"

if [ -d "$FILEPATH" ]

then

if [ -e $FILEPATH/if3.sh ]

then

echo "if3.sh is exist"

else

touch $FILEPATH/if3.sh

echo “if3.sh make cpmlete...successed.”

fi

else

{

mkdir -p $FILEPATH

touch $FILEPATH/if3.sh

echo “if3.sh make cpmlete...successed.”

}

fi

如果不想用上面的 else,还想用 if,写法如下:

if [ -e "$FILEPATH/if3.sh" ]

then

echo "$FILEPATH/if3.sh is exist"

fi

if [ ! -d "$FILEPATH" ]

then

mkdir -p $FILEPATH && touch $FILEPATH/if3.sh

fi

检测磁盘使用量:

#!/bin/bash

a=`df -m | grep root |awk '{print $4}'`

if (( $a < 100M ))

then

echo "/ litte 100M"

else

echo "/ more than 100M"

fi

检测内存使用量:

[root@server2 ~]# free -m | awk '/cache\:/ {print $NF}'

438

[root@server2 ~]# free -m | grep buffers |awk '{print $4}'| grep ^[0-9]

437

上面两种方法都是可以的,在执行效率上第一种方法比较好

#!/bin/bash

a=`free -m | grep buffers |awk '{print $4}'| grep ^[0-9]'`

if (( $a < 100 ))

then

echo "/ litte 100M"

else

echo "/ more than 100M"

fi

检测系统内存剩余量,如果小于 1000M 发送邮件给系统管理员

#!/bin/bash

cur_free=`free -m | grep buffers |awk '{print $4}'| grep ^[0-9]`

chars="current memory is $cur_free"

if (( $cur_free < 1000 ))

then

echo $chars

echo $chars | mail -s "$chars" 1020659371@qq.com

fi

crontab -e

* * * * * /bin/sh /root/memery.sh >&/dev/null

多分支举例:

a=$1

b=$2

if [ $# -ne 2 ]

then

echo "Usage:sh $0 num1 num2"

exit 1

fi

if [ $a -gt $b ]

then

echo "yes,$a > $b"

elif [ $a -eq $b ]

then

echo "yes,$a = $b"

else

echo "yes,$a < $b"

fi

加入对数字的判断:

a=$1

b=$2

if [ $# -ne 2 ]

then

echo "Usage:sh $0 num1 num2"

exit 1

fi

[ -n "`echo $1 | sed 's/[0-9]//g'`" ] && echo "第 一 个 参 数 必 须 为 数 字 " &&

exit 1

[ -n "`echo $2 | sed 's/[0-9]//g'`" ] && echo "第 二 个 参 数 必 须 为 数 字 " &&

exit 1

if [ $a -gt $b ]

then

echo "yes,$a > $b"

elif [ $a -eq $b ]

then

echo "yes,$a = $b"

else

echo "yes,$a < $b"

fi

扩展:判断字符串是否为数字的多种方法

法一:sed 加正则表达式

命令行传参:

组合语法判断 1:

[ -n "`echo $num |sed 's/[0-9]//g'`" -a -n "`echo $2 | sed 's/[0-9]//g'`" ] && echo "两个参

数都必须为数字" && exit 1

组合语法判断 2:

[ -n "`echo $num |sed 's/[0-9]//g'`" -a -n "`echo $2 | sed 's/[0-9]//g'`" ] && {

echo "两个参 数都必须为数字"

exit 1

}

普通变量判断:

[ -n "`echo $num |sed 's/[0-9]//g'`" ] &&echo "第二个参数都必须为数字" && exit 1

条件表达式,大括号的用法

[ -n "`echo $num |sed 's/[0-9]//g'`" ] && {

echo "第二个参数都必须为数字"

exit 1

}

法二:变量的子串替换加正则表达式

[root@server2 ~]# num=hy2015

[root@server2 ~]# [ -z "`echo "${num//[0-9]/}"`" ] && echo 1 || echo 0

0

[root@server2 ~]# num=2015hy2015

[root@server2 ~]# [ -z "`echo "${num//[0-9]/}"`" ] && echo 1 || echo 0

0

法三:变量的子串替换加正则表达式(特殊判断思路)

思路:如果 num 长度不为 0,并且把 num 中的非数字部分删除,然后看结果是不

是等于 num 本身,如果两者都成立就是数字。

-n "num" #->如果 num 长度不为 0 表达式

"$num" = "${num//^[0-9]/}" #->把 num 中的非数字部分删除,然后看结果是不是等

于 num 本身,如果两者都成立就是数字。

[root@server2 ~]# [ -n "$num" -a "$num" = "${num//[^0-9]/}" ] && echo "it is num"

测试:

[root@server2 ~]# num=2015

[root@server2 ~]# [ -n "$num" -a "$num" = "${num//[^0-9]/}" ] && echo "it is num"

it is num

法四:expr 计算判断

[root@server2 ~]# num=2015

[root@server2 ~]# expr $num + 0 >/dev/null 2>&1

[root@server2 ~]# [ $? -eq 0 ] && echo int

int

 

 

 

邮箱:g2hy@qq.com




阅读(3768) | 评论(0) | 转发(0) |
0

上一篇:shell笔记_01

下一篇:shell笔记_04

给主人留下些什么吧!~~