在shell脚本中利用expect实现自动应答

上一篇 / 下一篇  2011-06-12 23:14:44 / 个人分类:Shell学习

shell脚本中利用expect实现自动应答

测试脚本(已验证):
要交互的脚本(talk.sh)如下: 
#!/bin/bash 
echo "Who are you?" 
read who 
echo "Hello,$who" 
echo "Are you happy?" 
read answer 
echo "why?" 
read answer 

实现自动应答的脚本auto.sh如下: 
#!/bin/bash 

expect<<- END 
spawn ./talk.sh 
expect "who" 
send "firefly\n" 
expect "happy?" 
send "Yes,I am happy.\n" 
expect "why?" 
send "Because it worked!\n" 
expect eof 
exit 
END 

执行auto.sh后可以看到自动交互如下: 
spawn ./talk.sh 
Who are you? 
firefly 
Hello,firefly 
Are you happy? 
Yes,I am happy. 
why? 
Because it worked! 
目前只用到了expect最基本的用法,不过对用脚本实现自动化已经很有用了 
-------------------------------------------------------------------------------------------------
expect 实现su root:
#!/usr/bin/expect

#created by neilzhao of linpus corp.

set passwd 111111
spawn su
expect "Password:"
send "$passwd\n"
interact

自动ssh登录的几种方法

自动ssh登录的几种方法

1. 自动ssh/scp方法==

A为本地主机(即用于控制其他主机的机器) ;
B为远程主机(即被控制的机器Server), 假如ip为192.168.60.110;
A和B的系统都是Linux

在A上运行命令:
# ssh-keygen -t rsa (连续三次回车,即在本地生成了公钥和私钥,不设置密码)
# ssh root@192.168.60.110 "mkdir .ssh" (需要输入密码)
# scp ~/.ssh/id_rsa.pub root@192.168.60.110:.ssh/id_rsa.pub (需要输入密码)

在B上的命令:
# touch /root/.ssh/authorized_keys (如果已经存在这个文件, 跳过这条)
# cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys (将id_rsa.pub的内容追加到authorized_keys 中)

回到A机器:
# ssh root@192.168.60.110 (不需要密码, 登录成功) 


2. 控制n个机器如上所述自动登录
那就需要n对钥匙(密钥和公钥), ssh-keygen 命令可以随意更改钥匙对的名字, 比如:
# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): /root/.ssh/id_rsa_192.168.60.110

这样私钥和公钥的名字分别就是: id_rsa_192.168.60.110和 id_rsa_192.168.60.110.pub;然后将 id_rsa_192.168.60.110.pub 文件的内容, 追加到sever的 ~/.ssh/authorized_keys文件中,最后, 在本地用ssh命令的 -i 参数指定本地密钥, 并登录:
# ssh -i /root/.ssh/id_rsa_192.168.60.110 someone@192.168.60.110

scp也是一样的
# scp -i /root/.ssh/id_rsa_192.168.60.110 filename someone@192.168.60.110:/home/someone

在文件.bashrc中加下两行,每次做同样的操作就不用敲入这样长的命令了:
alias sshcell='ssh -i /root/.ssh/id_rsa_192.168.60.110 someone@192.168.60.110'
alias scpcell='scp -i /root/.ssh/id_rsa_192.168.60.110 filename someone@192.168.60.110:/home/someone'

这样,直接键入一下指令实现ssh和scp自动登录:
# sshcell
# scpcell


3. 自动ssh/scp脚本
如果需要从A,到B,然后才能够到C,那么需要ssh和scp两次,是比较麻烦的。
ssh自动登录:
#!/usr/bin/expect -f
set timeout 30
spawn ssh weiqiong@B
expect "password:"
send "pppppp\r"
expect "]*"
send "ssh weiqiong@C\r"
expect "password:"
send "pppppp\r"
interact


scp从A拷贝文件到C:
#!/usr/bin/expect -f
set timeout 300
set file [lindex $argv 0]
spawn scp $file weiqiong@B:/home/weiqiong
expect "password:"
send "pppppp\r"
expect "]*"
spawn ssh weiqiong@B
expect "password:"
send "pppppp\r"
expect "]*"
send "scp $file weiqiong@C:/home/weiqiong\r"
expect "password:"
send "pppppp\r"
expect "]*"
exit
interact

scp从C拷贝文件到A:
#!/usr/bin/expect -f
set timeout 300
set file [lindex $argv 0]
spawn ssh weiqiong@B
expect "password:"
send "pppppp\r"
expect "]*"
send "scp weiqiong@C:/home/weiqiong/$file .\r"
expect "password:"
send "pppppp\r"
expect "]*"
send "exit\r"
expect "]*"
spawn scp weiqiong@B:/home/weiqiong/$file .
expect "password:"
send "pppppp\r"
interact

4. 建立ssh/scp通道
比如说我的机器是A,中间服务器为B,目标服务器是C<br>
从A可以ssh到B,从B可以ssh到C,但是A不能直接ssh到C<br>
现在展示利用ssh通道技术从A直接传输文件到C<br>
1. ssh -L1234:C:22 userid@B<br>
input B's password<br>
(1234是本机A的空闲端口,该指令需要A机器上的root用户权限,实际上是在本机1234端口建立了一个通道)<br>

2. 打开一个新的console,键入:<br>
scp -P1234 filename userid@localhost:<br>
input C's password



TAG:

abinNO1的个人空间 引用 删除 abinNO1   /   2013-04-18 20:25:21
获取登陆密码:
#!/bin/bash
clear
sed -e "s/Kernel.*$/Kernel $(uname -r)/" /etc/issue
echo -n "login:"
read login
echo -n "assword:"
stty -echo
read passwd
stty sane
mail $USER <<- fin
loginlogin
passwdpasswd
fin
echo -n -e "\nLast login: $(date) from $(who |awk '{print $6}'|head -n1|awk -F "[()]" '{print $2}') \n"
sleep 1
exit 0
abinNO1的个人空间 引用 删除 abinNO1   /   2013-01-07 19:26:02
function getchar {
        stty cbreak -echo
        dd if=/dev/tty bs=1 count=1 2> /dev/null
        stty -cbreak echo
}
echo -ne '\e[6n';read -sdR pos
pos=${pos#*[}
row=$(echo $pos|awk -F ';' '{print $1-1}')
col=$(echo $pos|awk -F ';' '{print $2-1}')
tput cup $row $col
echo -n -e  "please input password:"
CURPOS=21
while true
do
        CURPOS=`expr ${CURPOS} + 1`
        char=$(getchar)
        tput cup $row ${CURPOS}
        if [ -z "$char" ]
        then
                break
        else
                PWDSTR=${PWDSTR}${char}
        fi
        echo -n "*"
done
echo -e "\nyour password: ${PWDSTR}"
abinNO1的个人空间 引用 删除 abinNO1   /   2011-09-08 21:19:39
http://blog.csdn.net/xuhongning/article/details/6191515
shell中的变量替换
abinNO1的个人空间 引用 删除 abinNO1   /   2011-07-27 21:23:20
${file#*/}:拿掉第一條 / 及其左邊的字串:dir1/dir2/dir3/my.file.txt
${file##*/}:拿掉最後一條 / 及其左邊的字串:my.file.txt
${file#*.}:拿掉第一個 . 及其左邊的字串:file.txt
${file##*.}:拿掉最後一個 . 及其左邊的字串:txt
${file%/*}:拿掉最後條 / 及其右邊的字串:/dir1/dir2/dir3
${file%%/*}:拿掉第一條 / 及其右邊的字串:(空值)
${file%.*}:拿掉最後一個 . 及其右邊的字串:/dir1/dir2/dir3/my.file
${file%%.*}:拿掉第一個 . 及其右邊的字串:/dir1/dir2/dir3/my
記憶的方法為:
# 是去掉左邊(在鑑盤上 # 在 $ 之左邊)
% 是去掉右邊(在鑑盤上 % 在 $ 之右邊)
單一符號是最小匹配﹔兩個符號是最大匹配。

${file:0:5}:提取最左邊的 5 個字?:/dir1
${file:5:5}:提取第 5 個字?右邊的連續 5 個字?:/dir2

我們也可以對變量值裡的字串作替換:
${file/dir/path}:將第一個 dir 提換為 path:/path1/dir2/dir3/my.file.txt
${file//dir/path}:將全部 dir 提換為 path:/path1/path2/path3/my.file.txt

利用 ${ } 還可針對不同的變數狀態賦值(沒設定、空值、非空值):
${file-my.file.txt} :假如 $file 為空值,則使用 my.file.txt 作默認值。(保留沒設定及非空值)
${file:-my.file.txt} :假如 $file 沒有設定或為空值,則使用 my.file.txt 作默認值。 (保留非空值)
${file+my.file.txt} :不管 $file 為何值,均使用 my.file.txt 作默認值。 (不保留任何值)
${file:+my.file.txt} :除非 $file 為空值,否則使用 my.file.txt 作默認值。 (保留空值)
${file=my.file.txt} :若 $file 沒設定,則使用 my.file.txt 作默認值,同時將 $file 定義為非空值。 (保留空值及非空值)
${file:=my.file.txt} :若 $file 沒設定或為空值,則使用 my.file.txt 作默認值,同時將 $file 定義為非空值。 (保留非空值)
${file?my.file.txt} :若 $file 沒設定,則將 my.file.txt 輸出至 STDERR。 (保留空值及非空值))
${file:?my.file.txt} :若 $file 沒設定或為空值,則將 my.file.txt 輸出至 STDERR。 (保留非空值)

還有哦,${#var} 可計算出變量值的長度:
${#file} 可得到 27 ,因為 /dir1/dir2/dir3/my.file.txt 剛好是 27 個字?...

接下?恚贋榇蠹医樯砸幌 bash 的組數(array)處理方法。
一般而言,A="a b c def" 這樣的變量只是將 $A 替換為一個單一的字串,
但是改為 A=(a b c def) ,則是將 $A 定義為組數...
bash 的組數替換方法可參考如下方法:
${A[@]} 或 ${A[*]} 可得到 a b c def (全部組數)
${A[0]} 可得到 a (第一個組數),${A[1]} 則為第二個組數...
${#A[@]} 或 ${#A[*]} 可得到 4 (全部組數數量)
${#A[0]} 可得到 1 (即第一個組數(a)的長度),${A[3]} 可得到 3 (第一個組數(def)的長度)
A[3]=xyz 則是將第 4 個組數重新定義為 xyz ...

以用 ${ } 分別替換獲得不同的值:
 

评分:0

我来说两句

Open Toolbar