接着上篇,version1只是实现了简单的功能,但是易用性还有待提高,我们来看看有什么可以改进的地方
可改进点
- version1实现的需要用户输入两次密码(scp和ssh),如何能在执行脚本的时候免交互
思路1:使用秘钥文件
考虑过后不可行,因为此工具的目的就是安装软件,只需执行一次,如果用生成秘钥文件的方式将会比version1更不好使用思路2:使用expect,可以不用多次输入密码静默安装,有关expect我的另一篇笔记有详细记录
expect:免交互自动化ssh
- 协程循环,用户没法退出,ctrl+c不友好
- 拆开,执行一次安装一台远端机器
实现version2
有三个文件主入口文件remote_install.sh
和两个被调用文件scp_expect.sh
install_expect.sh
version2使用expect实现了不用多次输入的静默安装方式,但是执行expect需要执行机器先安装expect,所以做了一点小兼容,如果机器装了expect,则静默安装,如果机器没装expect静默安装失败,则手动输入密码安装
- remote_install.sh
#!/bin/bash
function help()
{
#usage
cat << HELP
------------------------------------------------------------------------------
please input 4 parameters in order:
1st: path of xxx package at local host,
2nd: ip of the host which xxx will install
3rd: root's paasword of the host you inputted just now(2nd parameter)
4th: param4
Example:
bash remote_install.sh /opt/test/xx.zip 192.168.0.2 YourPaasWord param4
HELP
}
function install()
{
#read -a array
array=($1 $2 $3 $4)
echo ${array[*]}
# copy package to remote host
expect scp_expect.sh ${array[0]} ${array[1]} ${array[2]}
# compatible , if there is no expect, input paasword manually
if (( $? ))
then
scp ${array[0]} root@${array[1]}:/
fi
echo "bash setup.sh -param ${array[3]}"
# install package
expect install_expect.sh ${array[1]} ${array[2]} ${array[3]}
# compatible , if there is no expect, input paasword manually
if (( $? ))
then
ssh root@${array[1]} "mkdir -p /opt/test && \
cd /opt/test && \
cp /xx-*.zip ./ && \
unzip xx-*.zip && \
cd /opt/test/bin && \
bash setup.sh -param ${array[3]} "
# bash setup.sh -param ${array[3]} >/dev/null 2>&1 &"
fi
}
#while [ 1 ]
#do
if [ $# != 4 ]
then
help
exit
fi
install $1 $2 $3 $4
sleep 1
#done
- scp_expect.sh
#!/usr/bin/expect
set timeout 30
set path [lindex $argv 0]
set hostname [lindex $argv 1]
set password [lindex $argv 2]
spawn scp $path root@$hostname:/
expect {
"(yes/no)?" {
send "yes\r"
expect "assword:"
send "$password\r"
}
"assword:" {send "$password\r"}
}
#interact
expect eof
exit
- install_expect.sh
#!/usr/bin/expect
set timeout 30
set hostname [lindex $argv 0]
set password [lindex $argv 1]
set param3 [lindex $argv 2]
spawn ssh root@$hostname "mkdir -p /opt/test && \
cd /opt/test && \
cp /xx-*.zip ./ && \
unzip xx-*.zip && \
cd /opt/test/bin && \
bash setup.sh -param $param3 "
expect "assword:"
send "$password\r"
expect {
"ename:" {
send "All\r"
expect eof
exit
}
timeout {exit}
eof {exit}
}
遇到的问题
- 如何判断expect执行失败
cd mytestdir
if (( $? )); then rm * ; fi
可改进点
明文输入密码不够安全,可参考如下方式解决输入密码界面不显示问题
#!/bin/bash
echo -n "Please enter your password:"
stty -echo
read password
echo -e "\nyou password is:$password"
stty echo
Reference:
http://blog.csdn.net/wang7dao/article/details/7724917
http://blog.csdn.net/qingsong3333/article/details/77542921