shell 非交互处理
1.expect
expect可以用来实现非交互的功能,是根据脚本与其他交互式程序“对话”的程序。在脚本之后,Expect知道程序可以期望什么,正确的响应应该是什么。解释语言提供分支和高级控制结构来引导对话。 此外,用户可以根据需要控制并直接进行交互,然后将控制权返回给脚本。
1.1 实例1.非交互式ssh登陆
[klaus@localhost chapt5]$ cat ssh_login.sh
#!/usr/bin/expect
set user [lindex $argv 0]
set ip [lindex $argv 1]
set timeout 30
spawn ssh $user@$ip
expect {
"yes/no" { send "yes\r";exp_continue }
"password:" { send "asd123\r" }
}
interact
[klaus@localhost chapt5]$ ./ssh_login.sh klaus 192.168.84.130
spawn ssh klaus@192.168.84.130
klaus@192.168.84.130's password:
Activate the web console with: systemctl enable --now cockpit.socket
Last login: Thu Feb 6 09:39:11 2020 from 192.168.84.129
1.2 ssh远程拷贝文件
[klaus@localhost chapt5]$ cat ssh_cp.sh
#!/bin/bash
user=klaus
rpm -q expect &>/dev/null
if [ ! $? -eq 0 ];then
sudo yum install expect &>/dev/null
echo "expect has been installed!"
fi
if [ ! -f ~/.ssh/id_rsa ];then
ssh-keygen -P "" -f ~/.ssh/id_rsa
fi
for ip in `cat ip.txt`
do
{
ping -c1 -W1 $ip &>/dev/null
if [ $? -eq 0 ];then
/usr/bin/expect <<-EOF
spawn scp -r /home/klaus/Desktop/shell/chapt5/hh.c $user@$ip:/home/klaus/Desktop/
EOF
fi
}&
done
wait
echo "finished..."
[klaus@localhost chapt5]$ ./ssh_cp.sh
spawn scp -r /home/klaus/Desktop/shell/chapt5/hh.c klaus@192.168.84.130:/home/klaus/Desktop/
hh.c 100% 0 0.0KB/s 00:00
finished...
其中个别会出现port 22: Connection refused,lost connection,可能是防火墙的问题,端口号拒绝访问也有可能是端口没打开
sudo firewall-cmd --zone=public --add-port=22/tcp --permanent
sudo firewall-cmd --reload
2.交互总结
expect脚本执行方式和shell不一样,我们同时也可以在shell里面引用expect(见实例2.1),或者甚至其他,如python一样;脚本的赋值方式也不太一样,expect用的是[lindex $argv 0],下面实现一个远程创建用户的实例
2.1 远程创建用户
[klaus@localhost chapt5]$ cat ssh_useradd.sh
#!/bin/bash
user=$1
ip=$2
password=asd123
ping -c1 -W1 $ip &>/dev/null
if [ $? -eq 0 ];then
/usr/bin/expect<<-EOF
spawn ssh $user@$ip
expect
{
"yes/no" { send "yes\r";exp_continue}
"password:" { send "asd123\r"}
}
set timeout 10
expect "*$"
send "sudo useradd alice\r"
expect "$user:"
send "$password\r"
expect "*$"
send "id alice\r"
expect "*$"
send "exit\r"
expect eof
EOF
else
echo "Network unreachable, connection error!"
fi
执行结果如下
[klaus@localhost chapt5]$ ./ssh_useradd.sh klaus 192.168.84.130
spawn ssh klaus@192.168.84.130
Activate the web console with: systemctl enable --now cockpit.socket
Last login: Thu Feb 6 11:59:37 2020 from 192.168.84.129
[klaus@localhost ~]$ sudo useradd alice
[sudo] password for klaus:
[klaus@localhost ~]$ id alice
uid=1001(alice) gid=1001(alice) groups=1001(alice)
[klaus@localhost ~]$ exit
logout
Connection to 192.168.84.130 closed.