3. OS이야기/03. Shell Script

[UNIX/LINUX] 자동화를 위한 interactive 스크립트 - expect (2) 예제

알 수 없는 사용자 2014. 5. 14. 08:37

이번 글에서는 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문 등을 사용할 수 있습니다.