Bash 脚本:在控制台中自动执行命令

Bash 脚本:在控制台中自动执行命令

我通过一个简单的 bash 脚本连接到 VPN,我想在计算机启动时运行该脚本,因此,我需要它完全自动化。但是,该脚本将运行“openconnect --jupiper”并随后询问我的凭据(大约 3-4 秒后,当它获取连接时)。

我想让它在找到一些文本后(最快且更精确的方式)或在设定的延迟后(愚蠢且不太精确的方式)输出我的凭据。

有没有办法在设置的延迟后或返回某些文本(例如正则表达式匹配)后输出命令?

答案1

为了自动化命令,我多年来一直使用预计。模拟交互式会话非常有用,无论是在处理确实需要交互性的顽固命令时,还是在与网络上的活动设备或其他服务器交互时。我仍然用它来登录活动设备,获取一些统计数据并执行自动备份。

Expect 是一个根据脚本与其他交互式程序“对话”的程序。按照脚本,Expect 知道程序可以期待什么以及正确的响应应该是什么。解释性语言提供分支和高级控制结构来指导对话。此外,用户可以在需要时直接进行控制和交互,然后将控制权返回给脚本。

使用 Expect 脚本自动执行任务

作为示例,我编写了一个用于测试 POP 服务的 Expect 脚本:

#!/bin/sh
# \
exec expect "$0" ${1+"$@"}

set force_conservative 0  ;# set to 1 to force conservative mode even if
                          ;# script wasn't run conservatively originally
if {$force_conservative} {
        set send_slow {1 .1}
        proc send {ignore arg} {
                sleep .1
                exp_send -s -- $arg
        }
}

set timeout -1
spawn telnet 127.0.0.1 110
match_max 100000
expect {
"Hello"    { send -- "USER [email protected]\r"; exp_continue
       }
"assword" { send -- "PASS password\r" ; exp_continue
       }
"logged"   {
         send -- "LIST 1\r" ; exp_continue
   }
-re "failed|denied"   { exit
       }
"OK 1" { send -- "QUIT\r"; }
}

根据我与 @cas 的对话,我还想指出,简单的正则表达式期望语言子集对于简短的自动化脚本/[非常]粗糙的原型以及 bash 很有用。

如果需要对输出进行更复杂的处理,则可以/更好地使用另一种编程语言来完成交互式处理。

例如,在Python中,期待,或者甚至在 C 中,使用libexpect或者迷你预期

最近,随着 DevOps 运动的发展,您还获得了一整套新的[和旧的]框架来自动化系统任务,例如安西布尔,木偶,盐。

然而,它们确实需要学习曲线和更多资源。我个人比较喜欢 Ansible。

Ansible 提示:使用 Ansible 运行交互式脚本

答案2

我实际上无法让“openconnect”正确地与所有命令行参数一起工作,所以我最终为其制作了一个 Expect 脚本。

Rui F Ribeiro 的答案完全是关于金钱的,但是,我需要更多的研究才能让一切正常运转,包括次要的东西、变量等等。

为了让在这里看到这个问题的人感兴趣,我发布了解决原始问题用例的脚本,不是因为它是一个替代方案,而是因为它是 Rui F Ribeiro 知识共享的“扩展”。

#!/usr/bin/expect -f

set vpn_url "vpn.domain.com"
set vpn_username "theuser"
set vpn_password "thepassword"
set ubuntu_username "theubuntuloginuser"
set ubuntu_password "theubuntuloginpass"

set force_conservative 0  ;# set to 1 to force conservative mode even if
        ;# script wasn't run conservatively originally
if {$force_conservative} {
  set send_slow {1 .1}
  proc send {ignore arg} {
    sleep .1
    exp_send -s -- $arg
  }
}

set timeout -1
spawn $env(SHELL)
match_max 100000
send -- "sudo LD_LIBRARY_PATH=\"/usr/local/lib\" openconnect --juniper --no-cert-check $vpn_url -u $vpn_username\r"
expect {
  "password for $ubuntu_username:" {
    send -- "$ubuntu_password\r"
  }
}
expect -exact "password:"
send -- "$vpn_password\r"
expect eof

相关内容