| |
제 목 : 여러 서버에 일괄 명령을 위한 expect 스크립트
작성자 : 좋은진호(truefeel, http://coffeenix.net/ )
작성일 : 2007.5
정리일 : 2007.8.6(월)
여러대의 서버가 있고, 이 서버에 일괄적으로 동일한 명령을 줘야할 상황이 있다고 하자. 이런 상황에서 각 서버에 일일히 접속한 다음에, 명령을 내리고, 로그 아웃한다는 것은 손발이 고생하는 작업이 아닌가. 이러한 무모한(?) 작업은 다음과 같은 문제가 있다.
- 너무나도 지루한 작업이다.
- 시간이 너무 오래 걸린다. (짧은 시간에 반드시 모든 서버에 적용해하는 상황이면 더더욱 문제다.)
- 깜빡하고 작업하지 않은 서버가 생길 수 있다.
- 실행해야할 명령이 많을 때, 명령중 하나를 빼먹은 서버가 생길 수 있다.
1. 자동 접속 후 명령을 실행하는 expect 스크립트
이러한 문제를 expect 스크립트로 해결해보자. 다음은 지정한 서버에 자동으로 접속해서 명령을 실행하는 expect 스크립트이다.
| |
#!/usr/bin/expect --
#
# 서버접속 -> root로 명령 실행후 종료
#
# 2006.11.22
# Made by 좋은진호(truefeel, http://coffeenix.net/ )
set timeout 7
set server [lindex $argv 0]
set cmd [lindex $argv 1]
set logout_flg [lindex $argv 2]
set sleeptime 0.3
set sleeptime2 1
# default
set pass "일반유저_PW_입력하세요"
set pass_root "root_PW_입력하세요"
# server 1 (기본 root PW가 다른 서버들)
if { $server == "truefeel1" || $server == "truefeel2" || $server == "truefeel3" } {
set pass_root "root_PW_입력하세요"
}
# server 2 (기본 root PW가 다른 서버들)
if { $server == "w1" || $server == "w2" } {
set pass_root "root_PW_입력하세요"
}
# server 3 (기본 사용자 PW가 다른 서버들)
if { $server == "coffeenix1" || $server == "coffeenix2" } {
set pass "일반유저_PW_입력하세요"
}
# Mesg
set login_msg "assword:"
set prompt_msg "truefeel"
# ------------------------------------------
# option 확인
if { $cmd == "" } {
send "Usage : ./cmd.exp <Server> <Command> \[logout flag\] \n\n"
send " logout flag = 1 : 명령 실행 후에 자동으로 로그아웃\n"
send " logout flag 미지정 : 명령만 실행하고, 로그아웃은 하지 않음\n"
exit
}
# ------------------------------------------
spawn ssh $server
# login
expect $login_msg
sleep $sleeptime
send "$pass\r"
sleep $sleeptime
send "\r"
# su
expect $prompt_msg
sleep $sleeptime
send "su -\r"
expect $login_msg
send "$pass_root\r"
#
sleep $sleeptime
send "$cmd\r"
sleep $sleeptime2
# logout
if { $logout_flg == "1" } {
send "exit\r"
sleep $sleeptime
send "exit\r"
sleep $sleeptime
}
interact
| |
* Download : http://coffeenix.net/truefeel/files/expect/cmd.exp.txt
위 스크립트는 Linux, FreeBSD에서 모두 사용이 가능하며, 사용 방법은 다음과 같다.
| | # ./cmd.exp <접속할 서버> <명령어 나열> [자동_로그아웃_여부=1]
| |
스크립트는 너무나 간단하다. 스크립트를 크게 나눠보면, 첫번째 변수설정 부분, 2번째 옵션 체크 부분, 3번째 서버에 접속해서 명령을 내리는 부분으로 나뉜다.
2군데 정도만 살펴보자.
| |
17 # default
18 set pass "일반유저_PW_입력하세요"
19 set pass_root "root_PW_입력하세요"
20
21 # server 1 (기본 root PW가 다른 서버들)
22 if { $server == "truefeel1" || $server == "truefeel2" || $server == "truefeel3" } {
23 set pass_root "root_PW_입력하세요"
24 }
| |
17라인부터는 접속할 사용자의 PW와 root PW를 적는다. 서버에 따라 PW가 다르면 if 문을 통해서 별도로 지정할 수도 있다. 그 아래에 expect, sleep, send 가 반복적으로 쓰인 부분은 서버에 접속해서 su 명령으로 root로 변경하고, 지정한 명령을 실행하는 과정이다.
| |
74 # logout
75 if { $logout_flg == "1" } {
76 send "exit\r"
77 sleep $sleeptime
78 send "exit\r"
79 sleep $sleeptime
80 }
| |
이 부분은 명령 실행 후에 사용자가 원하면, 자동으로 로그아웃을 한다. exit가 2번 쓰인 것은 한번은 root -> 일반사용자로 전환을, 그 다음은 logout을 위한 것이다.
간단한 사용 예제다. 첫번째줄은 t1.coffeenix.net 서버에 접속한 후 리부팅을 하고, 두번째줄은 ls와 'cat /etc/fstab' 명령을 내린 후 자동으로 로그 아웃(3번째 옵션으로 '1'을 지정했음)을 한다.
| |
사용예)
./cmd.exp t1.coffeenix.net "ls;pwd;shutdown -r now"
./cmd.exp t1.coffeenix.net "ls;cat /etc/fstab" 1
| |
2. 여러 서버에 접속하기 위한 shell script
앞에 소개한 expect 스크립트는 지정한 1대의 서버에 접속하여 명령을 실행한다. 처음에 우리가 원하던 것은 여러 대의 서버에 접속하는 것이었다. 여러 대의 접속은 shell script로 처리했다.
| | #!/bin/sh
#
# 접속할 server를 공백으로 구분하여 나열
SERVER="$SERVER server1 server2 server3 server4 server5 server6"
SERVER="$SERVER www1 www2 www3 www4 www5"
# cmd.exp 경로
EXP="$HOME/bin/cmd.exp"
# 실행할 명령어를 ; 로 구분하여 나열 (예. ls;cd /etc )
CMD=""
# 명령 실행 후 자동 로그아웃하려면 1을 입력
OPT=""
# -------------------------------
for s in $SERVER
do
case "$s" in
*)
$EXP ${s} "$CMD" $OPT
;;
esac
sleep 0.5
done
| |
이 때 /etc/resolv.conf 의 search 옵션에는 서버의 도메인명을 적어주는게 편하다. 이를 테면 search coffeenix.net 로 설정해두면, ssh server1.coffeenix.net 으로 하지 않고 ssh server1 명령으로만으로도 접속할 수 있게 된다.
3. 관련 expect 스크립트
* expect 프로그래밍 예 (글 좋은진호)
http://coffeenix.net/board_view.php?bd_code=112
* expect 프로그래밍 예 두번째 (글 좋은진호)
http://coffeenix.net/board_view.php?bd_code=115
* 스위치장비 접속/명령용 expect 스크립트 (2006.1, 글 좋은진호)
http://coffeenix.net/board_view.php?bd_code=1327
|