expect命令简介
Expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。常用语ssh和telnet等需要进行人机交互的命令。
以前写过一个expect实现ssh跳转登录的例子:http://blog.youkuaiyun.com/koastal/article/details/52434314
基本结构
## 如果expect文件不存在,需要安装 yum install expect
#!/usr/bin/expect
## 设置脚本超时时间
set timeout 30
## 执行spawn之后的命令
spawn ssh -l root 192.168.238.130
## 如果执行结果包含expect之后的内容,则继续执行,否则退出
expect "password:"
## 模拟人工发送数据
send "root\r"
## 执行完成后保持交互状态,把控制权交给控制台,可以进一步人工操作
interact
HTTP和SMTP的报文格式
具体报文格式参照,php通过sock实现http和smtp的文章:http://blog.youkuaiyun.com/koastal/article/details/53149689
shell发送HTTP请求
expect发送GET请求
基本格式
#!/usr/bin/expect
set timeout 30
spawn telnet 127.0.0.1 80
expect "]"
send "GET /demo.php?name=zhezhao&age=23 HTTP/1.1\r"
send "Host: 127.0.0.1\r"
send "Connection: close\r"
send "\r\r"
interact
expect发送POST请求
基本格式
#!/usr/bin/expect
set timeout 30
set data "name=zhezhao&age=23"
set length [string length $data]
spawn telnet 127.0.0.1 80
expect "]"
send "POST /demo.php HTTP/1.1\r"
send "Host: 127.0.0.1\r"
send "Content-type:application/x-www-form-urlencoded\r"
send "Content-length:$length\r"
send "Connection: close\r\r"
send "$data\r"
interact
shell模拟curl发送HTTP请求
## 发送GET请求
./curl.sh "http://127.0.0.1/demo.php?name=zhezhao&age=23"
## 发送POST请求
./curl.sh -d "name=zhezhao&age=23" "http://127.0.0.1/demo.php"
因为使用except了执行脚本,所以需要使用Tcl语法编写代码(因为except基于Tcl)。
Tcl语法相关资料可以参考:
http://www.yiibai.com/tcl/
http://blog.chinaunix.net/uid-25324849-id-3191069.html
http://blog.sina.com.cn/s/blog_4b3c1f950102e4n5.html
http://blog.youkuaiyun.com/dulixin/article/details/2203908
#!/usr/bin/expect
set timeout 30
set tag [lindex $argv 0]
set option "-d"
if {$tag == $option} {
set method POST
set data [lindex $argv 1]
set url [lindex $argv 2]
set length [string length $data]
} else {
set method GET
set url [lindex $argv 0]
}
set port 80
set path /
set tag [string last : $url]
if {$tag != -1 && $tag != 4} {
## 用户手动给出了端口号
## 通过: 进行分割
set arr [split $url ":"]
if {[llength $arr] == 3} {
set host [lindex $arr 1]
set tmp [lindex $arr 2]
} else {
set host [lindex $arr 0]
set tmp [lindex $arr 1]
}
set host [string trimleft $host "//"]
## 通过/ 进行分割
set arr [split $tmp "/"]
for {set i 0} {$i < [llength $arr]} {incr i} {
if {$i == 0} {
set port [lindex $arr $i]
} else {
append path [lindex $arr $i]
append path /
}
}
} else {
## 通过: 进行分割
set tmp $url
set arr [split $url ":"]
if {[llength $arr] == 2} {
set tmp [lindex $arr 1]
}
## 通过/ 进行分割
set tmp [string trimleft $tmp "//"]
set arr [split $tmp "/"]
for {set i 0} {$i < [llength $arr]} {incr i} {
if {$i == 0} {
set host [lindex $arr $i]
} else {
append path [lindex $arr $i]
append path /
}
}
}
## 校正path
if {[string length $path] > 1} {
set path [string trimright $path "/"]
}
spawn telnet $host $port
expect "]"
send "$method $path HTTP/1.1\r"
send "Host: $host:$port\r"
if {$method == "POST"} {
send "Content-type:application/x-www-form-urlencoded\r"
send "Content-length:$length\r"
}
send "Connection: close\r\r"
if {$method == "POST"} {
send "$data\r"
}
interact
shell通过实现smtp协议发送邮件
基本格式
#!/usr/bin/expect
set timeout 60
spawn telnet smtp.163.com 25
expect "220"
#和服务器打招呼
send "HELO localhost\r"
expect "250"
#验证用户和密码
send "AUTH LOGIN 发件人邮箱base64编码\r"
expect "334"
send "发件人邮箱密码base64编码\r"
expect "235"
#书写信封
send "MAIL FROM:<发件人邮箱>\r"
expect "250"
send "RCPT TO:<收人邮箱>\r"
expect "250"
#书写新建内容
send "DATA\r"
expect "354"
send "from:发件人邮箱\r"
send "to:收人邮箱\r"
send "subject:server error\r"
send "MIME-Version:1.0\r"
send "content-type:text/plain\r\r"
send "let us become MI boy\r"
send ".\r"
expect "250"
#邮件发送成功,断开连接
send "qiut"
通用脚本
./mail.sh 12345@qq.com "代码如诗" "好事好事~"
#!/usr/bin/expect
set mailto [lindex $argv 0]
set subject [lindex $argv 1]
set body [lindex $argv 2]
set timeout 60
spawn telnet smtp.163.com 25
expect "220"
#和服务器打招呼
send "HELO localhost\r"
expect "250"
#验证用户和密码
send "AUTH LOGIN 发件人邮箱base64编码\r"
expect "334"
send "发件人邮箱密码base64编码\r"
expect "235"
#书写信封
send "MAIL FROM:<发件人邮箱>\r"
expect "250"
send "RCPT TO:<$mailto>\r"
expect "250"
#书写新建内容
send "DATA\r"
expect "354"
send "from:发件人邮箱\r"
send "to:$mailto\r"
send "subject:$subject\r"
send "MIME-Version:1.0\r"
send "content-type:text/plain\r\r"
send "$body\r"
send ".\r"
expect "250"
#邮件发送成功,断开连接
send "qiut"
python通过smtp发送邮件
#!/usr/bin/python
# -*- coding: utf-8 -*-
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
import smtplib
from_addr = "XXX@163.com";
password = "XXXX";
to_addr = "XXXX@qq.com";
smtp_server = "smtp.163.com";
msg = MIMEText('<html><body><h1>Hello</h1>' +
'<p>send by <a href="http://www.python.org">Python</a>...</p>' +
'</body></html>', 'html', 'utf-8');
msg['From'] = from_addr;
msg['To'] = to_addr;
msg['Subject'] = Header(u'来自SMTP的问候……', 'utf-8').encode();
server = smtplib.SMTP(smtp_server, 25)
server.set_debuglevel(1)
server.login(from_addr, password)
server.sendmail(from_addr, [to_addr], msg.as_string())
server.quit()
参考文章: