블로그 이미지
OSSW(Open Source System SoftWare

calendar

      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Notice

2014. 5. 14. 08:37 3. OS이야기/03. Shell Script

이번 글에서는 expect 스크립트에 대한 예제를 통해 이해를 돕는 시간을 갖도록 하겠습니다.

 

(2) 예제


#!/bin/expect


set target "[lindex $argv 0]"
set rootid "[lindex $argv 1]"
set oldpwd "[lindex $argv 2]"
set newpwd "[lindex $argv 3]"
spawn telnet $target
expect -timeout 5 "*ogin:"
send "$rootid\n"
expect -timeout 5 "*assword:"
send "$oldpwd\n"
sleep 2
expect -timeout 5 "#|>"
send "passwd\n"
expect -timeout 5 "New password:"
send "$newpwd\n"
expect -timeout 5 "Re-enter root's new password:"
send "$newpwd\n"

expect eof


    a. 내부변수 선언 및 외부변수 세팅

#!/bin/expect


set target "[lindex $argv 0]"
set rootid "[lindex $argv 1]"
set oldpwd "[lindex $argv 2]"

set newpwd "[lindex $argv 3]"


set 명령은 내부변수를 선언하기 위한 명령어입니다.

 

set target [변수값] 이라고 하면 target 이란 변수를 생성하여 '변수값'을 할당하겠다는 뜻이지요.

 

변수값 자리에 문자열이나 숫자같은 고정값을 하드코딩해 주어도 되지만, 여기서는 외부로부터 입력 변수를 받아 처리하기 위해 "[lindex $argv 0]" 이란 값을 사용했습니다.

 

외부변수로 입력된 값중에 제일 첫번째 값을 가져다가 target 변수에 세팅하겠다는 것입니다.

 

rootid, oldpwd, newpwd 등도 외부변수로 입력된 값중에 각각 두번째, 세번째, 네번째 값을 가져다가 세팅하게 됩니다.

 

    b. 실행 서비스 설정


spawn telnet $target


spawn 명령을 통하여 target 시스템에 접근할 서비스를 telnet 으로 세팅합니다.

 

target 변수에는 IP address 혹은 /etc/hosts 파일에 도메인 세팅이 되어 있는 경우 hostname이 들어오게 되겠죠.

 

    c. 패스워드 변경 수행


expect -timeout 5 "*ogin:"                                     // '*ogin:' 문자열이 뜨기를 5초간 기다림
send "$rootid\n"                                                    // rootid 변수에 할당된 값을 보내고 엔터(\n)를 누름
expect -timeout 5 "*assword:"                              // '*assword:' 문자열이 뜨기를 5초간 기다림
send "$oldpwd\n"                                                  // oldpwd 변수에 할당된 값을 보내고 엔터(\n)를 누름
sleep 2                                                                  // 2초간 waiting
expect -timeout 5 "#|>"                                        // '#'이나 '>' 문자열이 뜨기를 5초간 기다림
send "passwd\n"                                                   // passwd 명령을 보내고 엔터(\n)를 누름
expect -timeout 5 "New password:"
send "$newpwd\n"
expect -timeout 5 "Re-enter root's new password:"

send "$newpwd\n"



expect 명령을 사용하여 'ogin:' 으로 끝나는 문자열을 기다립니다.

 

시스템마다 로그인하려 할 때, 소문자로 'login:' 이 뜨는 경우도 있고 대문자로 'Login:' 이 뜨는 경우도 있어 제일 앞을 '*(asterisk)' 로 처리했습니다.

 

-timeout 5 옵션은 '*ogin:' 이란 문자열이 뜨기를 5초동안 기다리겠다는 것입니다.

 

네트워크의 성능에 따라 시스템에 접속할 때 로그인 프롬프트가 뜨는 시간이 조금씩 다르기 때문에 최소 5초 정도의 여유를 주는 것이 좋습니다.

 

5초 이후에도 해당 문자열이 뜨지 않으면 다음에 나오는 send 명령을 그냥 수행시켜 버립니다.

 

expect -timeout 5 "#|>" 명령 구문은 로그인 후에 해당 시스템의 프롬프트가 떨어지길 기다리고, 그 프롬프트의 제일 마지막 문자열이 '#' 이나 '>' 이길 기다립니다.

 

예제에서는 '#' 과 '>' 만 나열하였지만, 혹시나 프롬프트에 '$' 나 ']' 와 같은 다른 문자열이 마지막에 들어가 있다면 이러한 문자열들도 expect 명령 구문에 포함시켜야 합니다.

 

    d. expect 스크립트 종료 선언


expect eof



expect eof 명령 구문을 사용하여 expect 스크립트를 명시적으로 종료합니다.

 

해당 구문을 사용하지 않을 경우, 스크립트가 정상 종료하지 않은 상태로 남아있게 되어 Ctrl + c 명령 등을 통해 강제 종료해야 합니다.

 

이렇게 expect 스크립트를 모두 작성하였다면 이제 실행해야겠죠?

 

    e. expect 실행


./aix_change_pwd.exp 192.168.63.1 root root password



expect 스크립트의 확장자는 .exp 로 하시면 됩니다.

 

위와 같이 input 변수를 주고 실행한다면 192.168.63.1 IP를 가진 시스템에 root 계정으로 접근하여 기존 패스워드인 root 를 password 로 바꾸게 됩니다.

 

막상 알고보면 별거 없는데 제가 말주변이 없어서 설명을 좀 어렵게 적어놓은 듯 싶네요..;;;;

 

아주 기본적인 예제에 대해서만 설명해 놓았으나, expect 스크립트에도 bash 나 ksh 처럼 if문이나 for문 등을 사용할 수 있습니다.

posted by 박현명

댓글을 달아 주세요

2014. 5. 13. 15:13 3. OS이야기/03. Shell Script

이번 글에서는 자동화를 위해 유용하게 사용할 수 있는 expect 란 스크립트에 대해서 말씀 드리도록 하겠습니다.

 

expect 는 telnet이나 ftp와 같이 interactive한 환경이 필요한 곳에서 특정 문자열을 기다리고(expect), 정해진 문자열을 자동으로 보내는(send) 등의 처리를 하는 스크립트 언어입니다.

 

가령, A라는 서버에서 B라는 서버의 패스워드를 바꾸려 한다고 하면, telnet을 이용하여 B서버로 로그인하고 password 명령을 이용해 기존 패스워드와 새로운 패스워드를 차례로 입력하는 일련의 과정들을 거치게 됩니다.

 

하지만, 이 expect 를 이용하면 그런 절차들을 일일이 거칠 필요 없이 스크립트 하나만 돌림으로써 문제를 해결할 수 있습니다.

 

expect 스크립트를 사용하려면 bash나 ssh 등 여타 서비스들과 마찬가지로 시스템 상에 expect 모듈이 설치되어 있어야 하며, expect 설치 시에는 tcl과 tk 라는 두 가지 의존성을 가진 모듈이 함께 필요합니다.


(1) 기본 사용법

 

    a. 스크립트 선언


#!/bin/expect


bash나 ksh 등의 shell script 를 수행하기 위해서도 스크립트문 안에 위와 같이 선언을 해줘야 하듯, expect도 같은 방식으로 선언해 주어야 합니다.

 

expect 의 설치 위치가 bin 디렉토리 밑이 아니라면 bin 디렉토리 아래로 심볼릭 링크를 해주어야 합니다.

 

    b. target 시스템 설정


set target 192.168.63.1


해당 expect 스크립트를 수행할 target 시스템을 설정하는 부분입니다.

 

    c. 실행할 서비스 설정


spawn telnet $target



어떤 서비스를 이용하여 target 시스템에 접근할 것인지를 설정하는 부분으로, spawn 명령은 상호대화(interactive)할 프로그램을 띄우기 위한 목적으로 사용합니다.

 

    d. 예상되는 문구 설정


expect [-re] 예상문구                 // ex. expect -re "login:"



위에 나열한 순서로 target 시스템에 telnet 접근했을 때, 제일 먼저 뜨는 것은 ' login: ' 이라는 문구일 것입니다.

 

그러한 경우에 옆에 주석으로 달아놓은 것처럼 expect -re "login:" 이라고 설정하면 됩니다.

 

-re 옵션은 정규 표현식(regular expression)을 위해 사용합니다.

 

가령, expect -re "a*" 라고 설정하였다면, a, aa, aaa, aaaa, ... 등의 문자열과는 매치(match)하지만 ab, ac 등의 문자열과는 매치하지 않고,

 

expect "a*" 라고 설정하였다면, aa, ab, ac 등과 같은 문자열과 매치합니다.

 

    e. 원하는 값 보내기


send 원하는 값                           // ex. send "root"



예상되는 문구가 정상적으로 스크립트에서 인지되었다면 인제 그에 맞는 값을 target 시스템에 던져야겠죠?

 

target 시스템에 root로 로그인하고자 한다면 위와 같이 send "root" 라고 설정하면 됩니다.

 

    f. delay time 설정


sleep 자연수



시스템마다 조금씩 차이가 있는 것이 telnet을 이용하여 시스템에 접속하고 login 계정을 입력한 후 엔터를 치면, password 입력 프롬프트가 바로 안 나오고 1~2초 후에 보이는 경우가 있습니다.

 

그런 시스템에서 이 sleep 명령을 주지 않고 expect 다음에 send 명령을 바로 사용하면 멍~ 때리는 현상이 발생하게 됩니다.

 

예상되는 문구가 뜨기도 전에 target 시스템에 문자열을 날려 버리기 때문이지요.

 

expect 라는 자동화 스크립트의 특성상 한번 그렇게 문자열이 앞당겨져서 날라가게 되면 다음에 나오는 명령들도 줄줄이 앞당겨져서, 예상문구를 기다리지도 않고 날라가게 됩니다.

 

그러면 스크립트가 더 이상 수행되지 않고 멍 때리는 현상이 발생하지요.

 

그러므로 expect 스크립트에선 어떤 시스템에도 종속되지 않게 sleep 을 잘 사용하여 표준화하는 것이 중요합니다.

 

이러한 expect 스크립트에 대한 자료는 구글링을 아무리 해도 많지 않기에 expect 스크립트를 사용하시려는 분들께 도움이 되었으면 합니다.

 

다음 글에서는 예제를 통해 더 자세히 살펴보도록 하겠습니다.

posted by 박현명

댓글을 달아 주세요

  1. 네모 2015.01.13 14:55  Addr Edit/Del Reply

    많은도움이 되었습니다. 고맙습니다.

prev 1 next