1 SHELL脚本中的函数
1.1 函数介绍:
函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程。
它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,而是shell程序 的一部分 。
函数和shell程序比较相似,区别在于:
Shell程序在子Shell中运行,而Shell函数在当前Shell中运行。
因此在当前Shell中,函数可以对shell中变量进行修改。脚本中的函数是把一个复杂的语句定义成一个字符串的方法。
1.2 定义函数:
函数由两部分组成:函数名和函数体
语法一: function f_name { …函数体… }
语法二: function f_name () { …函数体… }
语法三: f_name (){ …函数体… } (此语法最为常用)
1.3 脚本中的函数示例:
示例一:
Host_Message()
{
read -p "please input your action:" Action
[ "Action"=="exit" ] && {exit 0}
[ "Action"=="user" ] && {echo "You are $USER"}
[ "Action"=="hostname" ] && {echo "you are client.westos.com"}
Host_Message
}
Host_Message
示例二:
vim test.sh
#!/bin/bash
ECHO()
{
echo -e "\033[${1}m$2\033[0m"
}
ECHO 31 ERROE
ECHO 32 OK
ECHO 31 ERROE
ECHO 32 OK
示例三:脚本的循环执行:
执行一串字符 直到输入exit才退出
vim test.sh
#!/bin/bash
ACTION()
{
read -p "please input a word :" WORD
[ "$WORD"="exit" -o "$WORD"="EXIT" ] && {
echo bye
exit 0
}||{
echo $WORD
}
ACTION
}
ACTION
1.4 使用函数编写具体脚本:
要求如下:使用交互式命令存在三个选项,创建、删除和退出。当创建时,若用户存在提示用户存在返回创建操作,直至创建成功。若用户不存在创建用户并输入密码,创建完成之后返回操作选项;当删除时,若用户不存在,返回操作选项,若用户存在删除用户返回操作选项;当退出时,直接退出。
1.5 简单介绍一下数组:
1.5.1 数组的定义:
何为数组?学过计算机编程语言的同学都知道,数组的特性就是一组数据类型相同的集合(不包括有一些编程语言提出来的关联数组的概念)。那么shell中数组是怎么定义的呢,我们来看两种数据类型:一是数值类型,二是字符串类型;虽然shell本身是弱类型的,但也可以这么区分。
数值类型的数组:一对括号表示数组,数组中元素之间使用“空格”来隔开。
举个列子:
arr_number=(1 2 3 4 5);
字符串类型数组:同样,使用一对括号表示数组,其中数组中的元素使用双引号或者单引号包含,同样使用“空格”来隔开。
arr_string=(“abc” “edf” “sss”); 或者 arr_string=(‘abc’ ‘edf’ ‘sss’);
1.5.2 数组的操作:
我们使用数值类型数组arr_number=(1 2 3 4 5)做为源数组进行相关的讲解:获取数组长度,读取某个下标的值,对某个下标赋值,删除、分配和替换以及遍历。提一个知识点,我们在shell里面想获取某个变量的值,使用 符 开 头 , 如 : 符开头,如: 符开头,如:a或者${a}即可。
获取数组长度
arr_length= ${#arr_number[*]}或${#arr_number[@]}均可,
即形式:${#数组名[@/*]} 可得到数组的长度。
读取某个下标的值
arr_index2=${arr_number[2]},即形式:${数组名[下标]}
对某个下标赋值
这里需要提出两个问题:
第一个问题是如果该下标元素已经存在,会怎么样?
答:会修改该下标的值为新的指定值。
例如:arr_number[2]=100,数组被修改为(1 2 100 4 5)
第二个问题是如果指定的下标已经超过当前数组的大小,如上述的arr_number的大小为5,指定下标为10或者11或者大于5的任意值会如何?
答:新赋的值被追加到数组的尾部。
<font face="微软雅黑"> 例如:arr_number[13]=13,数组被修改为(1 2 100 4 5 13)
删除操作
清除某个元素:unset arr_number[1],这里清除下标为1的数组;
清空整个数组:unset arr_number;
1.5.3 数组的简单示例:
a=(`df -h / | sed -n '/\/$/p'`)
echo ${a[4]}
2 for\while\if\case\expect语句
2.1 for循环语句:
1.for语句格式:
for num in 1 2 3
for num in {1..3}
for num in `seq 1 3` 或者 for num in `seq 1 2 10` #num为1到10,并且步长为2
do
done
示例一:将1~10主机通的主机ip抓出来
#!/bin/bash
for IP in {1..10}
do
ping -c1 -w1 172.25.254.$IP &> /dev/null
[ "o" = "$?" ] && {
echo 172.25.254.$IP
}
done
示例二:输出1-10,并且间隔为2
#!/bin/bash
for ((i=1;i<10;i+=2))
do
echo $i
done
示例三:输出1-10,并且间隔为2
#!/bin/bash
a=1
b=10
for i in `seq $a 2 $b`
do
echo $i
done
2.2 while循环语句:
while语句格式,当条件成立的时候,循环执行do下来的语句:
while 条件
do
done
while示例一:将uptime语句监视的系统负载十秒钟执行一次 并显示出来
while true (while 1=1 , until false)
do
echo `uptime`
sleep 10
done
while示例二:
#!/bin/bash
while true
do
read -p "please input word: " WORD
echo $WORD
done
2.3 if条件语句:
if语句格式:
if
then
elif
then
...
else (可以没有else,就是没有条件不存在时的操作,直接退出)
fi
示例:利用用户文件 密码文件建立用户 当文件个数或者文件不存在时都报错
(genent passwd root 检测root用户存不存在)
2.4 case条件语句:
case语句格式:
world1 )
action1
;;
world2)
action2
;;
.......
*)
action_last
esac
case语句示例:
#!/bin/bash
case $1 in
linux|LINUX|Linux)
echo westos
;;
westos|WESTOS|Westos)
echo linux
;;
lee|LEE|Lee
echo liu
;;
*)
echo error
esac
2.5 expect :自动应答语句:
expect 是自动应答命令用于交互式命令的自动执行
spawn 是expect中的监控程序,其运行后会监控命令提出的交互问题
send 发送问题答案给交互命令
exp_continue 表示当问题不存在时继续回答下面的问题
expecte eof 表示问题回答完毕退出expect环境
interact 表示问题回答完毕留在交互界面
set NAME [ lindex $argv 0 ] 定义变量 NAME为脚本后的第一个字符串
yum install expect
vim /mnt/ask.sh
#!/bin/bash
read -p "What's your name: " NAME
read -p "How old are: " AGE
read -p "what your favourite object: " OBJECT
read -p "Are you happy: " FEEL
echo $NAME is $AGE\'s old like $OBJECT feel $FEEL
当把脚本中一个问题删掉时,使用输入重定向应答有可能会导致错乱,所以需要expect
当把其中一个问题删掉 使用四个expect回答时 会卡在删掉的那个问题上
当把其中一个问题删掉 使用一个expect回答时 会自动跳过那个删掉的问题
示例一:自动应答上面所写的/mnt/ask.sh脚本
vim answer.exp
#!/usr/bin/expect
set NAME [ lindex $argv 0 ]
set AGE [ lindex $argv 1 ]
set OBJECT [ lindex $argv 2 ]
set FEEL [ lindex $argv 3 ]
spawn sh /mnt/ask.sh
expect{
"name" { send "$NAME\r" ; exp_continue }
"old" { send "$AGE\r" ; exp_continue }
"object" { send "$OBJECT\r" ; exp_continue }
"happy" { send "$FEEL\r" ; exp_continue }
}
expect eof
示例二:使用ip和密码可以ssh连接
#!/bin/bash
set IP [ lindex $argv 0 ]
set PASS [ lindex $argv 1 ]
spawn ssh root@$IP
expect {
"yes/no" { send "yes\r" ; exp_continue }
"password" { send "$PASS\r" }
}
interact
示例三:显示1-10通的主机的主机名
#!/bin/bash
Auto_SSH()
{
/usr/bin/expect <<EOF
spawn ssh root@$1 hostname
expect {
"yes/no" { send "yes\r" ; exp_continue }
"password" { send "westos\r" }
}
expect eof
EOF
}
for IP in {1..10}
do
ping -c1 -w1 172.25.254.$IP &> /dev/null
if [ "$?" = "0" ]
then
Auto_SSH 172.25.254.$IP | tail -n 1
fi
done
2.6 脚本中的语句控制器:
exit n 脚本退出,退出值为n
break 退出当前循环
continue 提前结束循环内部的命令,但不终止循环。也就是终止当此循环,开始下次循环
最后,编写脚本完成固定时间的倒计时: