6、使用expect调用passwd自动更改密码
#!/bin/bash
USER=mynameuser
PASS=oldpassword
NPASS=newpassword
expect << EOF
spawn passwd
expect "Changing password for ${USER}."
send "${PASS}\r"
expect "Enter new UNIX password:"
send "${NPASS}\r"
expect "Retype new UNIX password:"
send "${NPASS}\r"
expect eof;
EOF
7、完成对服务器的scp任务:
#!/usr/bin/expect
set timeout 10
set host [lindex $argv 0]
set username [lindex $argv 1]
set password [lindex $argv 2]
set src_file [lindex $argv 3]
set dest_file [lindex $argv 4]
spawn scp $src_file $username@$host:$dest_file
expect {
"(yes/no)?"
{
send "yes\n"
expect "*assword:" { send "$password\n"}
}
"*assword:"
{
send "$password\n"
}
}
expect "100%"
expect eof
说明:
(1)注意代码刚开始的第一行,指定了expect的路径,与shell脚本相同,这一句指定了程序在执行时到哪里去寻找相应的启动程序。代码刚开始还设定了timeout的时间为10秒,如果在执行scp任务时遇到了代码中没有指定的异常,则在等待10秒后该脚本的执行会自动终止。
(2)这个脚本设置了5个需要手动输入的参数,分别为:目标主机的IP、用户名、密码、本地文件路径、目标主机中的文件路径。如果将以上脚本保存为expect_scp文件,则在shell下执行时需要按以下的规范来输入命令:
./expect_scp 192.168.75.130 root 123456 /root/src_file /root/dest_file
以上的命令执行后,将把本地/root目录下的src_file文件拷贝到用户名为root,密码为123456的主机192.168.75.130中的/root下,同时还将这个源文件重命名为dest_file。
(3)spawn代表在本地终端执行的语句,在该语句开始执行后,expect开始捕获终端的输出信息,然后做出对应的操作。expect代码中的捕获的(yes/no)内容用于完成第一次访问目标主机时保存密钥的操作。有了这一句,scp的任务减少了中断的情况。代码结尾的expect eof与spawn对应,表示捕获终端输出信息的终止。
如果需要实现批量scp的任务,则需要再写一个shell脚本来调用这个expect脚本。
#!/bin/sh
list_file=$1
src_file=$2
dest_file=$3
cat $list_file | while read line
do
host_ip=`echo $line | awk '{print $1}'`
username=`echo $line | awk '{print $2}'`
password=`echo $line | awk '{print $3}'`
echo "$host_ip"
./expect_scp $host_ip $username $password $src_file $dest_file
done
指定了3个参数:列表文件的位置、本地源文件路径、远程主机目标文件路径。需要说明的是其中的列表文件指定了远程主机ip、用户名、密码,这些信息需要写成以下的格式:
IP username password
中间用空格或tab键来分隔,多台主机的信息需要写多行内容,如:
192.168.75.130 root 123456
192.168.75.131 knktc testpass
这样就指定了两台远程主机的信息。注意,如果远程主机密码中有“$”、“#”这类特殊字符的话,在编写列表文件时就需要在这些特殊字符前加上转义字符,否则expect在执行时会输入错误的密码。
执行脚本:
./batch_scp.sh ./hosts.list /root/src_file /root/destfile
用这两个脚本文件,就可以简单地完成批量scp的任务了。
六、综合例子
1、自动化脚本建立主机之间的SSH信任关系
#!/usr/bin/ksh
#usage ./ssh_trust.sh host1 user1 passwd1 host2 user2 passwd2
#即建立从user1@host1到user2@host2的ssh信任。
src_host=$1
src_username=$2
src_passwd=$3
dst_host=$4
dst_username=$5
dst_passwd=$6
#在远程主机1上生成公私钥对
Keygen()
{
expect << EOF
spawn ssh $src_username@$src_host ssh-keygen -t rsa
while 1 {
expect {
"password:" {
send "$src_passwd\n"
}
"yes/no*" {
send "yes\n"
}
"Enter file in which to save the key*" {
send "\n"
}
"Enter passphrase*" {
send "\n"
}
"Enter same passphrase again:" {
send "\n"
}
"Overwrite (y/n)" {
send "n\n"
}
eof {
exit
}
}
}
EOF
}
#从远程主机1获取公钥保存到本地
Get_pub()
{
expect << EOF
spawn scp $src_username@$src_host:~/.ssh/id_rsa.pub /tmp
expect {
"password:" {
send "$src_passwd\n";exp_continue
}
"yes/no*" {
send "yes\n";exp_continue
}
eof {
exit
}
}
EOF
}
#将公钥的内容附加到远程主机2的authorized_keys
Put_pub()
{
src_pub="$(cat /tmp/id_rsa.pub)"
expect << EOF
spawn ssh $dst_username@$dst_host "mkdir -p ~/.ssh;echo $src_pub >> ~/.ssh/authorized_keys;chmod 600 ~/.ssh/authorized_keys"
expect {
"password:" {
send "$dst_passwd\n";exp_continue
}
"yes/no*" {
send "yes\n";exp_continue
}
eof {
exit
}
}
EOF
}
Keygen
Get_pub
Put_pub