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뿐만 아니라 짧은 자동화 스크립트/[매우] 대략적인 프로토타입 제작에 유용하다는 점도 지적하고 싶습니다.

출력에 대해 더 복잡한 처리가 필요한 경우 다른 프로그래밍 언어를 사용하여 대화형 처리를 더 잘 수행할 수 있습니다.

예를 들어, 파이썬에서는예상하다, 또는 C에서도 다음을 사용합니다.libexpect또는작은 기대.

최근 DevOps 운동이 성장함에 따라 다음과 같은 시스템 작업을 자동화하기 위한 새로운(및 기존) 프레임워크가 많이 등장했습니다.안시푸르, 인형, 소금.

그러나 학습 곡선과 더 많은 리소스가 필요합니다. 저는 개인적으로 Ansible을 선호합니다.

Ansible 팁: Ansible로 대화형 스크립트 실행

답변2

실제로 모든 명령줄 인수에서 "openconnect"가 올바르게 작동하도록 할 수 없었기 때문에 결국 이에 대한 Expect 스크립트를 만들었습니다.

Rui F Ribeiro의 대답은 모두 돈에 관한 것입니다. 그러나 사소한 것, 변수 등을 포함하여 모든 것이 제대로 작동하려면 더 많은 연구가 필요합니다.

여기서 이 질문을 보는 모든 사람의 관심을 위해 원래 질문의 사용 사례를 해결하는 스크립트를 게시합니다. 이는 대안이기 때문이 아니라 Rui F Ribeiro의 Creative Commons에 대한 "확장"이기 때문입니다.

#!/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

관련 정보