여러대의 서버가 있고, 이 서버에 일괄적으로 동일한 명령을 줘야할 상황이 있다고 하자. 이런 상황에서 각 서버에 일일히 접속한 다음에, 명령을 내리고, 로그 아웃한다는 것은 손발이 고생하는 작업이 아닌가. 이러한 무모한(?) 작업은 다음과 같은 문제가 있다.
- 너무나도 지루한 작업이다.
- 시간이 너무 오래 걸린다. (짧은 시간에 반드시 모든 서버에 적용해하는 상황이면 더더욱 문제다.)
- 깜빡하고 작업하지 않은 서버가 생길 수 있다.
- 실행해야할 명령이 많을 때, 명령중 하나를 빼먹은 서버가 생길 수 있다.
1. 자동 접속 후 명령을 실행하는 expect 스크립트
이러한 문제를 expect 스크립트로 해결해보자. 다음은 지정한 서버에 자동으로 접속해서 명령을 실행하는 expect 스크립트이다.
* Download : http://coffeenix.net/truefeel/files/expect/cmd.exp.txt
위 스크립트는 Linux, FreeBSD에서 모두 사용이 가능하며, 사용 방법은 다음과 같다.
스크립트는 너무나 간단하다. 스크립트를 크게 나눠보면, 첫번째 변수설정 부분, 2번째 옵션 체크 부분, 3번째 서버에 접속해서 명령을 내리는 부분으로 나뉜다.
2군데 정도만 살펴보자.
17라인부터는 접속할 사용자의 PW와 root PW를 적는다. 서버에 따라 PW가 다르면 if 문을 통해서 별도로 지정할 수도 있다. 그 아래에 expect, sleep, send 가 반복적으로 쓰인 부분은 서버에 접속해서 su 명령으로 root로 변경하고, 지정한 명령을 실행하는 과정이다.
이 부분은 명령 실행 후에 사용자가 원하면, 자동으로 로그아웃을 한다. exit가 2번 쓰인 것은 한번은 root -> 일반사용자로 전환을, 그 다음은 logout을 위한 것이다.
간단한 사용 예제다. 첫번째줄은 t1.coffeenix.net 서버에 접속한 후 리부팅을 하고, 두번째줄은 ls와 'cat /etc/fstab' 명령을 내린 후 자동으로 로그 아웃(3번째 옵션으로 '1'을 지정했음)을 한다.
2. 여러 서버에 접속하기 위한 shell script
앞에 소개한 expect 스크립트는 지정한 1대의 서버에 접속하여 명령을 실행한다. 처음에 우리가 원하던 것은 여러 대의 서버에 접속하는 것이었다. 여러 대의 접속은 shell script로 처리했다.
이 때 /etc/resolv.conf 의 search 옵션에는 서버의 도메인명을 적어주는게 편하다. 이를 테면 search coffeenix.net 로 설정해두면, ssh server1.coffeenix.net 으로 하지 않고 ssh server1 명령으로만으로도 접속할 수 있게 된다.
- 너무나도 지루한 작업이다.
- 시간이 너무 오래 걸린다. (짧은 시간에 반드시 모든 서버에 적용해하는 상황이면 더더욱 문제다.)
- 깜빡하고 작업하지 않은 서버가 생길 수 있다.
- 실행해야할 명령이 많을 때, 명령중 하나를 빼먹은 서버가 생길 수 있다.
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 명령으로만으로도 접속할 수 있게 된다.