안녕하세요. 송기석입니다.

오늘 가져온 물건은 expect 입니다.

이 물건이 뭐하는 물건이냐면... 쉘 스크립트를 만들어 사용하다 보면 사용자의 입력이 필요한 경우가

있습니다. 이런 경우에 사용자 대신 필요한 값을 입력해 줄 수 있는 프로그램입니다.

사전적 뜻은 다음과 같습니다.


expect : 예상하다, 기대하다, 생각하다, 바라다, 기다리다


expect는 다른 응용 에플리케이션과 상호대화를(interactive) 하는 프로그램을 만들기 위해 만들어진 프로그램입니다.

expect는 어플리케이션의 표준출력을 분석함으로써 이루어 집니다. 단어의 뜻처럼 특정 문자열을 기다리고 있다가

특정 문자열이 나오면 그에 맞는 처리를 해줍니다. 이를 통해 자동화된 프로그램을 만들수 있습니다.

예시로 자동으로 로그인을 하려면 'login :'과 'password' 와 같은 표준출력 문자열을 통해서 값을 대신 입력해 주어 

처리 할수 있습니다.


expect를 사용하기 위해서는 패키지를 설치 해야 합니다.


# apt-get install expect


root@pkg:/# apt-get install expect

패키지 목록을 읽는 중입니다... 완료

의존성 트리를 만드는 중입니다

상태 정보를 읽는 중입니다... 완료

다음 패키지를 더 설치할 것입니다:

 tcl8.5

제안하는 패키지:

 tclreadline

다음 새 패키지를 설치할 것입니다:

 expect tcl8.5

0개 업그레이드, 2개 새로 설치, 0개 제거 및 0개 업그레이드 안 함.

1,150 k바이트 아카이브를 받아야 합니다.

이 작업 후 3,587 k바이트의 디스크 공간을 더 사용하게 됩니다.

계속 하시겠습니까 [Y/n]?  y

받기:1 http://ports.ubuntu.com/ubuntu-ports/ precise/main tcl8.5 armhf 8.5.11-1ubuntu1 [1,001 kB]

받기:2 http://ports.ubuntu.com/ubuntu-ports/ precise/main expect armhf 5.45-2 [150 kB]

내려받기 1,150 k바이트, 소요시간 5초 (193 k바이트/초)

debconf: delaying package configuration, since apt-utils is not installed

Selecting previously unselected package tcl8.5.

(데이터베이스 읽는중 ...현재 19283개의 파일과 디렉터리가 설치되어 있습니다.)

tcl8.5 패키지를 푸는 중입니다 (.../tcl8.5_8.5.11-1ubuntu1_armhf.deb에서) ...

Selecting previously unselected package expect.

expect 패키지를 푸는 중입니다 (.../expect_5.45-2_armhf.deb에서) ...

tcl8.5 (8.5.11-1ubuntu1) 설정하는 중입니다 ...

update-alternatives: /usr/bin/tclsh8.5 사용해서 자동 모드에서 /usr/bin/tclsh (tclsh) 제공.

expect (5.45-2) 설정하는 중입니다 ...

libc-bin에 대한 트리거를 처리하는 중입니다 ...

ldconfig deferred processing now taking place

root@pkg:/#


버전 확인.

root@pkg:/# expect -v

expect version 5.45

root@pkg:/#


이제 expect를 사용해 보겠습니다.

expect는 제가 쉘 스크립트를 만들어 사용하다 보니 사용자 입력이 필요한 부분들이 있어 그부분을 해결하기 위한

방법으로 expect를 테스트 해 본 것입니다.


실전 예제로 제가 SD 메모리를 포멧을 해보겠습니다.

스크립트는 다음과 같습니다.


test.sh

------------------------------------------------------------------------

#!/bin/bash


DEV_FILE=/dev/sdb1

FS=mkfs.ext3


echo -e "copy root file_system to $DEV_FILE "


$FS $DEV_FILE

------------------------------------------------------------------------


여기서 파일시스템은 ext3를 사용하고 SD 메모리는 /dev/sdb1 입니다.

이 쉘 스크립트를 실행하면 


root@pkg:~# ./test.sh

copy root file_system to /dev/sdb1

mke2fs 1.42 (29-Nov-2011)

Filesystem label=

OS type: Linux

Block size=4096 (log=2)

Fragment size=4096 (log=2)

Stride=0 blocks, Stripe width=0 blocks

242400 inodes, 967808 blocks

48390 blocks (5.00%) reserved for the super user

First data block=0

Maximum filesystem blocks=994050048

30 block groups

32768 blocks per group, 32768 fragments per group

8080 inodes per group

Superblock backups stored on blocks:

32768, 98304, 163840, 229376, 294912, 819200, 884736


Allocating group tables: done

Writing inode tables: done

Creating journal (16384 blocks): done

Writing superblocks and filesystem accounting information:


이와 같이 "information:"  부분에서 엔터가 필요합니다.

이 부분을 expect를 사용하여 해결해 보겠습니다.


expect.sh

------------------------------------------------------------------------

#!/usr/bin/expect -f


set timeout 100


spawn /home/pkg/test.sh


expect "information:"

send "\r"


interact

------------------------------------------------------------------------


쉘 스크립트를 간단히 설명하자면...

set timeout 를 사용하여 스크립트가 무한 대기 하는 것을 막기 위해 시간을 설정해 주었습니다.

spawn 은 감시하고 싶은 어플리케이션입니다. 이곳에서 아까 SD 메모리를 포멧하는 스크립트를 넣어 줍니다.

expect 는 특정 문자열을 감시 합니다. 

send 는 expect에서 감시하고 있는 문자열이 나오면 실행 해 줍니다. 여기서 "\r"은 엔터와 같습니다.

interact 는 스크립트 마지막에 넣어 줍니다.


이렇게 두개의 스크립트를 만들어 놓고 expect.sh 스크립트를 실행하면 SD 메모리를 포멧할 때 사용자 입력이 필요 없습니다.