강좌 & 팁
안녕하세요. 송기석입니다.
오늘 가져온 물건은 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 메모리를 포멧할 때 사용자 입력이 필요 없습니다.