在逻辑控制语句中会使用各种运算符和测试判断,可参见
http://iyull.blog.51cto.com/4664834/1884528
declare声明变量
declare -i sum=0:声明sum为整形
declare -x sum=0:声明为环境变量,相当于export
linux随机生成随机数
/dev/random
/dev/urandom
使用方法:echo -n $RANDOM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
生成10个随机数,并求出最大值和最小值
#/bin/bash
min=0
max=0
for
i
in
{1..10};
do
myran=$RANDOM
[ $i -
eq
1 ] && min=$myran
if
[ $i -
le
9 ];
then
echo
-n
"$myran,"
else
echo
"$myran"
fi
if
[ $myran -gt $max ];
then
max=$myran
fi
if
[ $myran -lt $min ];
then
min=$myran
fi
done
echo
"max is $max"
echo
"min is $min"
|
条件判断if
单分支if语句
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
if
判断条件;
then
stat3ment1
stat3ment2
...
fi
双分支
if
语句
if
判断条件;
then
stat3ment1
stat3ment2
...
else
stat3ment3
stat3ment4
...
fi
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
多分支/嵌套
if
语句
if
判断条件;
then
stat3ment1
...
elif
判断条件;
then
stat3ment2
...
elif
判断条件;
then
stat3ment3
...
else
statement4
...
fi
|
注:if中判断命令结果和状态的说明
1
2
3
4
5
6
7
8
|
#不加反引号表明获取命令执行状态即$?
if
ping
192.168.0.1 ;
then
echo
"192.168.0.1 is up"
fi
#加反引号表示获取命令执行结果,在下面if中没有实际意义。
if
`
ping
192.168.0.1`;
then
...
fi
|
迭代循环for
用于已知循环次数迭代使用
语法:
1
2
3
4
|
for
变量
in
列表
do
循环体
done
|
列表生成方法:
1、{1..100}:1-100
2、seq 100:1-100
3、seq 2 2 100:起始数为2,步进为2,结束数为100
4、`ls /var`:通过命令替换生成列表
例:计算100以内所有能被3整除的数的和
1
2
3
4
5
6
7
8
9
10
11
|
#!/bin/bash
#
sum
=0
for
i
in
{1..100}
do
if
[ $[$i%3] -
eq
0 ];
then
let
sum
=$[$
sum
+$i]
fi
done
echo
"$sum"
|
多重分支case
case结构用于多种情况的条件判断。类似于其他编程语言中的switch/case语句,但从语法形式上讲,有很大的不同。
语法:
1
2
3
4
5
6
7
8
9
10
11
|
case
字符串
in
模式)
语句
;;
模式2|模式二 )
语句
;;
模式3)
语句
;;
esac
|
提示:esac就是case反过来写。
示例:
根据用户输入,归档压缩文件
while循环
语法:
1
2
3
4
5
|
while
CONDITION
do
statement
...
done
|
注:满足CONDITTON开始循环,不满足退出循环
示例:计算100以内的正整数的和
1
2
3
4
5
6
7
8
9
10
|
#!/bin/bash
#
sum
=0
i=1
while
[ $i -
le
100 ]
do
let
sum
+=$i
let
i++
done
echo
$
sum
|
示例:每5秒钟检查一下user01是否登录,如果登录则退出
1
2
3
4
5
6
7
8
9
|
#!/bin/bash
#
user=`
who
|
grep
user01`
while
[ -z
"$user"
];
do
echo
"user01 not login"
user=`
who
|
grep
user01`
sleep
5
done
echo
"user01 login"
|
示例:
显示下面菜单给用户
d|D) show disk usages
m|M) show memory usages
s|S) show swap usages
quit) quit script
当用户选择完成,显示相应信息后,不退出,让用户再选择一次,再次显示相应内容,除非用户使用quit
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
|
#!/bin/bash
#
echo
"========d|D) show disk usages========"
echo
"========m|M) show memory usages========"
echo
"========s|S) show swap usages========"
echo
"========quit) quit script========"
read
-p
"please input list:"
list
while
[
"$list"
!=
'quit'
];
do
case
$list
in
d|D)
df
-Ph
;;
m|M)
memuse=`
free
-m |
grep
"buffers/cache"
|
awk
'{print $3}'
`
echo
"memory usage $memuse"
;;
s|S)
swapuse=`
free
-m |
grep
Swap |
awk
'{print $2}'
`
echo
"swap usages $swapuse"
;;
*)
echo
"Usage:please input d|D,m|M,s|S,quit please input "
quit
""
;;
quit)
exit
0
;;
esac
read
-p
"please input list:"
list
done
|
特殊用法一:
1
2
3
4
5
6
7
8
9
10
|
#死循环一
while
:
do
statement
done
#死循环二
while
true
do
statement
done
|
特殊用法二:
1
2
3
4
5
6
|
#从文件中读取内容并赋值给变量
while
read
LINE
do
statement
done
<
/etc/passwd
#从/etc/passwd中逐行取出内容并赋值给LINE变量。
|
逻辑判断中特殊判断
break:提前退出循环
continue:提前结束本轮循环,进入下一轮循环,一般是循环内设置条件,根据条件判断是否continue
示例:计算100以内偶数的和,当和大于5000时不在计算。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
while
循环实现
#!/bin/bash
i=0
sum
=0
while
[ $i -lt 1000 ];
do
let
i++
if
[ $[$i%2] -
eq
0 ];
then
let
sum
+=$i
echo
$i
fi
if
[ $
sum
-gt 5000 ];
then
break
fi
done
echo
$
sum
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
for
循环实现
#!/bin/bash
#
sum
=0
for
((i=0;i+=2;i<5000));
do
let
sum
+=$i
if
[ $
sum
-gt 5000 ];
then
break
fi
echo
$i
done
echo
$
sum
|
until循环
语法:
1
2
3
4
5
|
until
CONDITION
do
statement
...
done
|
注:不满足CONDITION开始循环,满足结束循环
练习:通过ping测试10.82.10.0-10.82.10.10之间所有主机是否在线,在线则显示“ip up”,不在线则显示“ip down”。分别使用while、until、for(两种形式)实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#while循环
#!/bin/bash
#
i=0
up=0
down=0
while
[ $i -
le
10 ];
do
ping
-c 1 -W 1 10.82.10.$i >
/dev/null
if
[ $? -
eq
0 ];
then
echo
-e
"\033[32m10.82.10.$i is up\033[0m"
let
up++
else
echo
-e
"\033[31m10.82.10.$i is down\033[0m"
let
down++
fi
let
i++
done
echo
-e
"\033[32m10.82.10.XXX up ip count $up\033[0m"
echo
-e
"\033[31m10.82.10.XXX down ip count $down\033[0m"
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#until循环
#!/bin/bash
#
i=0
up=0
down=0
until
[ $i -
ge
10 ];
do
ping
-c 1 -W 1 10.82.10.$i >
/dev/null
if
[ $? -
eq
0 ];
then
echo
-e
"\033[32m10.82.10.$i is up\033[0m"
let
up++
else
echo
-e
"\033[31m10.82.10.$i is down\033[0m"
let
down++
fi
let
i++
done
echo
-e
"\033[32m10.82.10.XXX up ip count $up\033[0m"
echo
-e
"\033[31m10.82.10.XXX down ip count $down\033[0m"
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#for循环1
#!/bin/bash
#
up=0
down=0
for
((i=0;i<10;i++));
do
ping
-c 1 -W 1 10.82.10.$i >
/dev/null
if
[ $? -
eq
0 ];
then
echo
-e
"\033[32m10.82.10.$i is up\033[0m"
let
up++
else
echo
-e
"\033[31m10.82.10.$i is down\033[0m"
let
down++
fi
done
echo
-e
"\033[32m10.82.10.XXX up ip count $up\033[0m"
echo
-e
"\033[31m10.82.10.XXX down ip count $down\033[0m"
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#for循环2
#!/bin/bash
#
up=0
down=0
for
i
in
{1..10};
do
ping
-c 1 -W 1 10.82.10.$i >
/dev/null
if
[ $? -
eq
0 ];
then
echo
-e
"\033[32m10.82.10.$i is up\033[0m"
let
up++
else
echo
-e
"\033[31m10.82.10.$i is down\033[0m"
let
down++
fi
done
echo
-e
"\033[32m10.82.10.XXX up ip count $up\033[0m"
echo
-e
"\033[31m10.82.10.XXX down ip count $down\033[0m"
|
函数
结构化编程,不能独立运行,需要调用时执行,可被多次调用
定义函数的两种方式
1
2
3
4
5
6
7
8
|
#方式一
function
FUNCNAME {
command
}
#方式二
FUNCNAME() {
command
}
|
1、引用函数执行结果并赋值
NAME=`FUNCNAME`
2、引用函数执行状态,此方式只能获取函数中最后一条命令的返回状态。因此不可作为信任条件。
FUNCNAME
echo $?
3、自定义函数执行状态
return # 定义函数返回状态值,需注意,函数中执行到retrun就会结束函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#示例,自定义函数返回状态值
#!/bin/bash
#
ADDUSER() {
USERNAME=liangstudy
if
!
id
=u $USERNAME &>
/dev/null
;
then
useradd
$USERNAME &>
/dev/null
echo
$USERNAME |
passwd
--stdin $USERNAME &>
/dev/null
return
0
else
return
1
fi
}
ADDUSER
if
[ $? -
eq
0 ];
then
echo
"add user finished"
else
echo
"add user failed"
fi
|
4、函数参数
1
2
3
4
5
6
7
8
9
10
11
|
#计算1-10之间相邻两个数字的和
#!/bin/bash
#
twosum() {
echo
$[$1+$2]
#引用参数$1,$2
}
for
i
in
{1..10};
do
let
j=$[$i+1]
echo
"$i plus $j is `twosum $i $j`"
#将函数结果引用并处理
done
|
示例:使用函数ping 192.168.1.1-30之间所有ip。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#!/bin/bash
#
Fping() {
ping
-c 1 -W 1 192.168.1.$1 &>
/dev/null
if
[ $? -
eq
0 ];
then
echo
-e
"\033[32m192.168.210.$1 is up\033[0m"
else
echo
-e
"\033[33m192.168.210.$1 is down\033[0m"
fi
}
for
i
in
{1..30};
do
Fping $i
done
|
示例:在主程序中,接收用户输入并传递给函数,判断用户是否存在,如果存在就返回UID和Shell,如果不存在,就提示并返回错误状态值,判断后不退出脚本,继续提示输入,输入q或者Q退出
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
|
#!/bin/bash
#
Fuser() {
id
$1 &>
/dev/null
if
[ $? -
eq
0 ];
then
UserUid=`
grep
"$1"
/etc/passwd
|
cut
-d: -f3`
UserShell=`
grep
"$1"
/etc/passwd
|
cut
-d: -f7`
echo
-e
"\033[32muser $1 UID is $UserUid and Shell is $UserShell \033[0m"
return
0
else
echo
-e
"\033[31muser $1 is not exist \033[0m"
return
1
fi
}
read
-p
"please input user name:"
UserName
until
[ $UserName == q -o $UserName == Q ];
do
case
$UserName
in
q|Q)
echo
"quit..."
exit
5
;;
*)
Fuser $UserName
;;
esac
read
-p
"please input user name:"
UserName
done
|