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

関連情報