default 今天晚自习快被这个小工具恶心死了,来记录一下问题

首先,因为这个工具特性就是能够执行交互式脚本,所以我先写了一个简单的python脚本

1
2
3
4
ip = input("请输入ip地址:\n")
port = input("请输入端口号:\n")
username = input("请输入用户名:\n")
password = input("请输入密码:\n")

运行脚本效果:

运行效果

之后,磨难来临。

1、首先安装,非常简单(debian)

1
$ root apt-get install -y expect

2、脚本常识接触(学习)

脚本以 #!/usr/bin/expect 开头,类似bash脚本

脚本以 .exp 或者 .ex 结束

  • spawn 新建一个进程,这个进程的交互由expect控制
  • expect 等待接受进程返回的字符串,直到超时时间,根据规则决定下一步操作
  • send 发送字符串给expect控制的进程
  • set 设定变量为某个值
  • exp_continue 重新执行expect命令分支
  • [lindex $argv 0] 获取expect脚本的第1个参数
  • [lindex $argv 1] 获取expect脚本的第2个参数
  • set timeout -1 设置超时方式为永远等待
  • set timeout 30 设置超时时间为30秒
  • interact 将脚本的控制权交给用户,用户可继续输入命令
  • expect eof 等待spawn进程结束后退出信号eof

加上某个前辈的实例(这个例子被人用烂了,找不到原创):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/usr/bin/expect -f

set timeout -1 //永远等待,不会超时
spawn ssh root@hostname1 //spawn 后面跟命令名称和参数

//如果匹配到*assword,那么发送密码,并进入下面的expect语句(uname -a语句)。
//如果匹配到yes/no,那么发送yes,并重新执行这个expect语句。

expect {
"*assword" {send "123456\r";}
"yes/no" {send "yes\r";exp_continue}
}

//匹配到*]#,那么运行uname -a命令
expect "*]#" {send "uname -a\r"}

send "exit\r" //退出远程登录

expect eof //结束spawn

//开始下一个命令
spawn ssh root@hostname2
expect {
"*assword" {send "123456\r";}
"yes/no" {send "yes\r";exp_continue}
}
expect "*]#" {send "uname -a\r"}
send "exit\r" //退出远程登录
expect eof //结束spawn

exit //退出expect脚本

其实,看到这里,结合翻阅的众多实例,我已经懂了这个软件大致是个什么用法了,但是我还是被他硬生生的坑去了不少时间,我这个恨啊!!!!

3、记录错误

(1)send后面的语句必须加 引号 :

你要是不加引号,他就给你报错,这是我send只发送了一个回车之后试出来的,而且报错还是真正错误的上一行的位置,虽然是我粗心了,但是这个语法报错我差评

N0txj1

(占了我最多时间)

(2)想要用exp_continue重复判断 :

首先要在前面的语句后面加上 ; (这叫啥号我忘记了,好像是分号),而且你不想看他报错给你看的话,expect块中的最后一个send后面不要加 exp_continue

(3)如果你的程序不执行了,并且不报错,嘿嘿:

一开始用着看他的写法,不管你觉得不觉得,反正我觉得,expect eof 就是类似于sql中的判断语句中的case when 中的end 这样的角色了,但他真的不是!他出现就意味着,你的一个脚本已经执行结束了,这条脚本命令不需要继续执行了,所以如果你之后还有针对这个脚本的命令,因为你的expect eof ,使后续命令全部失效。这是我血淋淋的经验,测试程序的时候,可以在最后加上一个expect eof 表示程序停止,看看是否有你想要输出的结果

(4)是不是expect后面加上个大括号很有安全感?

确实是可以加,但是加上了大括号,它的含义就是多匹配了,类似于switch,不过其实就算是加上大括号也可以写啦,程序不会报错的,但是也很有可能不会执行,如果你的大括号后面直接跟上匹配的字符,而不是换行写指令的话….,最好的方式就是单匹配,直接一行 expect “” 下一行send “” ,不会有任何问题

到这里,我的目的已经达到了,我就是写了一个脚本,让我的v2ray能够每一个周末重新执行删除安装的过程,并且给我的邮箱发送配置参数,用了我几天课余时间吧,最终做出来了,还是挺有趣的