Shell-08函数与Expect

你可能看到这个标题有疑问,函数与Expect有什么关系,对,他们没有关系,但是这个每一个单独写一个篇幅有点短,所以就写在一起了,哈哈!

函数

函数必须定义才可以使用

定义函数

方法一

函数名(){
	函数要实现的功能代码
}

方法二

function 函数名(){
	函数要实现的功能代码
}

调用函数

函数名 参数1 参数2

#!/bin/bash
factorial(){
factorial=1
for i in `seq $1`
do
	let factoral*=$i
done
echo "$1 的阶乘是 $factorial"
}
factorial $1

返回值

#return的值
#!/bin/bash
fun2(){
	read -p "enter num :"num
	return $[2*$num]  #return最高255
}

fun2
echo "fun2 return value: $?"

可以使用下面的方式
#!/bin/bash
fun2(){
	read -p "enter num :"num
	echo $[2*$num]  
}

result = `fun2`
echo "fun2 return value: $result"

传参数-位置参数

#!/usr/bin/bash
if [ $# -ne 3];then
	echo "usage:`basename $0`par1 par2 par3"
	exit
fi

fun3(){
	echo "$(($1 * $2 * $3))"
}

result =`fun3 $1 $2 $3`
echo "result is: $result"

传参数-数组

#!/usr/bin/bash
num=(1 2 3 )
num2=(2 3 4 )

array(){
	local factorial=1
	for i in $*
	do
		factorial=$[factorial * $i]
	done
	echo "$factorial"
}
#array $(num[@])
array ${num[*]} #数组所有元数值
array ${num2[*]} #数组所有元数值  

#!/usr/bin/bash
#for i 
for i in $@
do
	let sum =$sum + $i
done 
echo $sum

传参数-数组变量

#!/usr/bin/bash
num=(1 2 3)
num2=(2 3 4)
array(){
	#echo "all parameters:$*"
	local newarrary=(`echo $*`)
	local i
	for((i=0;i<$#;i++))
	do
		outarry[$i] = $((${newarray[$i]}*5))	
	done
	echo "${outarry[*]}"
}
reuslt=`array ${num[*]}`
echo ${result[*]}

reuslt=`array ${num2[*]}`
echo ${result[*]}



#!/usr/bin/bash
num=(1 2 3)

array(){
	local i
	lcoal outarry=()
	for i 
	do
		outarry[++j]=$[$i*5]	
	done
	echo "${outarry[*]}"
}
reuslt=`array ${num[*]}`
echo ${result[*]}
#函数接受位置参数 $1$2...$n
#函数接受数组变量 $* 或者$@
#函数使用参数的个数 $#
#函数将接受到所有参数赋值给数组 newarray=($*)

expect

​ 借助expect 处理交互的命令,可以将交互过程如 ssh 登录, ftp 登录等写在一个脚本上,使之自动化完成。尤其适用于需要对多台服务器执行相同操作的环境中,可以大大提高系统管理员的工作效率。

安装

[root@ansible ssh]# rpm -qa | grep expect
expect-5.45-14.el7_1.x86_64
[root@ansible ssh]# yum -y install expect

命令格式

expect [选项] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ]

  • -c:从命令行执行expect脚本,默认expect是交互地执行的

    示例:expect -c ‘expect “\n” {send “pressed enter\n”}’

  • -d:输出调试信息

    示例:expect -d ssh.exp

expect中的相关命令

  • spawn:启动新的进程
  • send:向进程发送字符串
  • expect:从进程接收字符串
  • interact:允许用户交互
  • exp_continue 匹配多个字符串时在执行动作后加此命令

expect语法

语法格式:模式-动作

单一分支模式

  • expect "hi" { send "You said hi\n" } #匹配到 hi 后,会输出"you said hi",并换行

多分支模式

  • expect "hi" { send "You said hi\n" } \ "hehe" { send “Hehe yourself\n" } \ "bye" { send "Goodbye\n" }
    匹配 hi, hehe, bye 中的任意字符串时, 发送相应字符串。下面是另外一种格式
  • expect { "hi" { send "You said hi\n" } "hehe" { send "Hehe yourself\n" } "bye" { send "Goodbye\n" } }

expect的使用条件

  • 执行 expect 不能以 bash file 的方式来执行 (开启子shell进程)

  • 必须通过 chmod +x file ; ./file 这样的方式 (不会开启子shell进程, 只在当前shell环境中执行)

  • expect 如果只交互一次如拷贝文件,结尾就使用 expect eof

  • 如果需要连续交互如登录远程主机执行各种命令结尾就需使用 interact

示例

expect实现ssh非交互登陆

#!/usr/bin/expect
set ip 192.168.110.2   #使用位置变量  [lindex $argv 0]
set user root #使用位置变量  [lindex $argv 1]
set password centos
set timeout 5 
apawn ssh $user@$ip
expect{
	"yes/no"{ send "yes\r";exp_continue }
	"password:" { send "$password\r" };
}
#直接退出  expect eof
interact
####后面是验证
expect "#"
send "useradd yangyang\r"
send "pwd\r"
send "exit\r"
expect eof

expect实现批量主机公钥推送

#!/usr/bin/bash
>ip.txt
rmp -1 expect &>/dev/null
if [ $? -ne 0 ];then
	
	yum -y install expect
fi

if [ ! -f ~/.ssh/id_rsa];then
	ssh-keygen -p "" -f ~/.ssh/id_rsa
fi

fro i in {2..254}
do
	{
		ip =192.168.110.$i
		ping -c1 -W1 $ip &>/dev/null
		if [ $? -eq 0 ];then
			echo "$ip" >> ip.txt
			/usr/bin/expect << -EOF
			spawn ssh-copr-id $ip
			expect{
				"yes/no" {send "yes\r";exp_continue}
				"password:" {send "contos\r"}
			}
			expect eof
			EOF
 		fi
	}&
done
wait


版权声明:本文为a13554371686原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。