用spawn和expect自动回答脚本的提问 制作无人值守脚本 真正一把梭 以233v334.sh为例

相信大家在使用了一段时间的各种一键脚本之后,会找到最适合自己的模式,也有了自己稳定的域名,UUID等参数。但是目前翻墙圈子里的一键脚本都喜欢做成大菜单的形式,这样每次使用的过程中, 都需要守在电脑前面选择各个选项,输入各个参数. 

那有没有无人值守的方法呢? 每次安装可以真正做到一把梭? 可以把安装的命令浓缩成一行,放到Xshell的快捷命令按钮里?下面会以233v334.sh为例,讲解如何用spawn和expect自动回答脚本的提问,制作无人值守脚本,真正做到一把梭。

先看疗效


安装 expect

apt install -y expect


基本原理

以安装 233脚本v3.34为例

先用 wget -N git.io/233v334.sh 下载脚本

然后在 bash 233v334.sh 的过程中自动回答问题

安装过程 Q&A 

请选择 [1-2](默认Default 1.安装): 直接回车
传输协议 Transport mode (默认Default 1. TCP):4
V2Ray 端口 Port (默认Default 63808): 直接回车
域名 Domain (例如:mydomain.com): ouyj.ga
Input 4 for IPv4, 6 for IPv6 [4/6]: 4
是否已经正确解析? Is resolution correct? [y]: y
是否自动配置TLS? Setup auto TLS? [Y/n] (默认Default Y): 直接回车
是否开启 网站伪装 和 路径分流 Setup fake website and hide V2Ray behind a path? [Y/n] (默认Default Y): 直接回车
分流的路径 Path (默认Default [21d49e1e62c9]): 直接回车
伪装的网址 Camouflage site (默认Default [https://zelikk.blogspot.com]): 直接回车
是否开启广告拦截(会影响性能)  [y/N] (默认Default N): 直接回车
是否配置 Shadowsocks [y/N] (默认Default N): 直接回车
按 Enter 回车键 继续....或按 Ctrl + C 取消. 直接回车

对应 expect send 写成 exp 脚本

spawn bash ./233v334.sh
expect "请选择*"
send "\r"
expect "*Transport mode*"
send "4\r"
expect "*Port*"
send "\r"
expect "*Domain*"
send "ougj.ga\r"
expect "Input 4 for IPv4, 6 for IPv6*"
send "4\r"
expect "*Is resolution correct*"
send "y\r"
expect "*Setup auto TLS*"
send "\r"
expect "*Setup fake website and hide V2Ray behind a path*"
send "\r"
expect "*Path*"
send "\r"
expect "*Camouflage site*"
send "\r"
expect "*广告拦截*"
send "\r"
expect "*Shadowsocks*"
send "\r"
expect "*Enter 回车键*"
send "\r"
expect eof

保存为比如 afk.exp

使用方法

expect afk.exp

VPS有可能会重装清空数据,总不能把 expect 脚本放在VPS上。所以我们传到GitHub上,要用的时候wget下载下来。像下面这样: 

wget -N git.io/233v334.sh && wget -N https://github.com/crazypeace/v2ray/raw/master/afk.exp && expect afk.exp

如果要做到刚重装过的VPS一行命令一把梭,那么就是:

apt update && apt install -y expect wget && wget -N git.io/233v334.sh && wget -N https://github.com/crazypeace/v2ray/raw/master/afk.exp && expect afk.exp


优化, 带参数

考虑到你可能会有好几台VPS, 安装过程中的域名和网络栈参数会不一样. 所以优化一下带上参数.

这里要用到 lindex $argv 0 这样的用法来引用参数。

exp脚本改动的地方为

set DOMAIN [lindex $argv 0]
set NETSTACK [lindex $argv 1]
#略
expect "*Domain*"
send "$DOMAIN\r"
expect "Input 4 for IPv4, 6 for IPv6*"
send "$NETSTACK\r"
#略

使用方法

expect afk.exp ougj.ga 4


优化, 同样的判断重复执行多次

有很多条都是直接回车使用默认值, 以此为思路把脚本缩短. 找到同样的关键字 Default,都输入直接回车. 而脚本中存在带Default关键字但是又不能直接回车的, 写在前面. 把Default的处理放在最后一个. 这里用到 exp_continue 

set DOMAIN [lindex $argv 0]
set NETSTACK [lindex $argv 1]

spawn bash ./233v334.sh
expect {
  "*Transport mode*" {
    send "4\r"
    exp_continue
  }
  "*Domain*" {
    send "$DOMAIN\r"
    exp_continue
  }
  "*Input 4 for IPv4, 6 for IPv6*"  {
    send "$NETSTACK\r"
    exp_continue
  }
  "*Is resolution correct*" {
    send "y\r"
    exp_continue
  }
  "*Ctrl + C*" {
    send "\r"
    exp_continue
  }
  "*Default*" {
    send "\r"
    exp_continue
  }
}


后记

用同样的思路,大家可以制作自己的 xui,warp等无人值守脚本。

--------

在expect选择关键字的时候,不要跨颜色。因为在变颜色的那里,其实有一个特殊字符。

原理跟 Xshell录制操作脚本要注意字体颜色 是一样的。

--------

我一开始以为expect是一个小功能,没想到有一本书是讲expect的。

https://www.oreilly.com/library/view/exploring-expect/9781565920903

后面跟上ch01.html就是第一章,以此类推。如:

https://www.oreilly.com/library/view/exploring-expect/9781565920903/ch04.html


参考

在写本文中间看了无数文章, 有一些目前用不到, 先记录一下. 感谢但不限于如下:

https://www.baeldung.com/linux/bash-interactive-prompts

https://www.cnblogs.com/yaokaka/p/13846407.html

https://xstarcd.github.io/wiki/shell/expect_description.html

https://my.oschina.net/u/3367404/blog/3064306

https://cloud.tencent.com/developer/article/1799462

https://cloud.tencent.com/developer/article/1721546

https://stdupanda.github.io/escape

https://developer.aliyun.com/article/516383


评论

The Hot3 in Last 30 Days

无服务器 自建短链服务 Url-Shorten-Worker 完整的部署教程

ClouDNS .asia免费域名 托管到CloudFlare开CDN白嫖Websocket WS通道翻墙 / desec.io