如何使用单独函数的输出更新 shell 脚本中的唯一字符串?

如何使用单独函数的输出更新 shell 脚本中的唯一字符串?

由于我的懒惰,我编写了一系列极其“混乱”的脚本来自动启动我的openvpn。我使用的配置文件来自 vpnbook.com/freevpn。

要获取密码,我使用:

lynx --dump --nolist vpnbook.com/freevpn | grep -i password | sort -u | cut -b 18,19,20,21,22,23,24

密码是从网站返回的。

然后,我使用expect脚本自动登录(用户名始终是vpnbook,但密码根据星期而变化):

#!/usr/bin/expect -f
spawn openvpn /vpn/vpnbook-ca1-tcp80.ovpn ### my vpn configuration file ###
expect "*?sername:*"
send -- "vpnbook\r"
expect "*?assword:*"
### This next line sends the password that changes by the week, which I...
###...unfortunately need to update manually (for lack of a better method):
send -- "weekly-password\r" 

我在尝试自动更新密码时遇到的问题:

1)我无法直接从expect环境调用lynx。

2)由于密码更改,我不确定如何用更新版本替换上周的唯一密码短语:

send -- "unique-previous-password\r" 

3)我不确定如何使用 lynx 函数输出的字符串作为输入变量来编辑上周的密码(位于我的期望脚本中)。

很明显,我不是“最聪明的”程序员(也不是最有效率的)。然而,归根结底,我唯一的目标是通过键入单个命令来完全初始化我的 VPN(正如我之前提到的,我很懒)。

任何帮助将不胜感激,谢谢!

答案1

在您的expect/tcl脚本中,您可以使用:

send "$env(PASSWORD)\r"

expect使用以下命令调用您的脚本:

PASSWORD=$(elinks -dump...) /path/to/your/expect/script

请注意,您可以使用cut -b18-24简称。

答案2

Stéphane 的解决方案非常优雅,但如果您不想每次都下载并解析密码,您可以保留两步过程,如下所示:

将您的密码检索命令修改为:

sed -e '$ d' -i .bak f && echo -n "send -- \"" >> f && lynx --dump --nolist vpnbook.com/freevpn | grep -i password | sort -u | cut -b 18-24 >> f && echo "\\r\"" >> f

为简洁起见,我将您的期望脚本文件称为f。实际上,它需要是完整的,/path/to/your/expect/script除非您已经与脚本位于同一目录中。

然后像往常一样调用您的期望脚本。

分解后,扩展命令的工作原理如下:

  • sed -e '$ d' -i .bak f找到最后一行 ( $)f并将其删除 ( d)。小心-e-i开关 - 它们在某些平台上是不同的/不支持的。明确指定交换机使用-e时的命令,意味着就地修改文件,保存扩展名的备份。-i-i.bak

  • &&如果上一个命令成功,则执行下一个命令。

  • echo -n "send -- \"" >> f将 send Expect 函数的第一部分附加到文件 ( >> f) 中,不带换行符 ( )。-n

  • lynx...您的原始命令,但结果附加到文件 ( >> f)。

  • echo "\\r\"" >> f附加发送期望函数的最后一部分。

相关内容