커피닉스, 시스템 엔지니어의 쉼터 커피향이 나는 *NIX
커피닉스
시스템/네트웍/보안을 다루는 곳
* HanIRC의 #coffeenix 방
[ 장비 및 회선 후원 ]
HOME > 시스템 관리 / 서버운영 도움말
검색 : 사이트 WHOIS 웹서버 종류

최적화 / 튜닝 / 성능개선 (6, 글 1, 자료 3)
디스크 쿼터(quota) (3, 글 1, 자료 3)
디스크 관리 / 파일시스템 / mount (34, 글 13, 자료 12)
백업(backup) / 시스템 복구 (14, 글 6, 자료 11)
서버운영 (8, 글 2, 자료 9)
프린터 관리 / 프린팅 (7)
패키지 관리 / 패치 / rpm (10, 글 5, 자료 1)
부팅, boot / LILO / GRUB (10, 글 5, 자료 9)
서버 모니터링 (10, 글 5, 자료 2)
로그인 / 로그아웃 (1)
로그(log) / syslog (5, 글 3, 자료 3)
메모리, 스왑(swap), 램디스크(ramdisk) (3, 글 2)
사용자 관리(계정 관리) (1, 자료 1)

  여러 서버에 일괄 명령을 위한 expect 스크립트 작성일 : 2007/08/06 22:58
 
  • 글쓴이 : 좋은진호 ( http://coffeenix.net/ )
  • 조회수 : 21612
          [ 이전화면 / 수정 ]   비밀번호 :     인쇄용 화면
      제  목 : 여러 서버에 일괄 명령을 위한 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

      커피닉스 카페 최근 글
    [06/16] [질문]SAN 스위치 브로드케이드 dcx8510-4 장비관련입니다.
    [04/22] Re: 영화속에 컴퓨터 이야기 ~스워드피쉬(2001)
    [10/20] Cross Compiler 깔
    [07/14] SSL АО
    [04/26] Re: 도스화면 원격조종 여부
    [04/25] 도스화면 원격조종 여부
    [10/30] Cshell에서 난수 설정
    [10/23] 공항철도주식회사 SE 구인 件
    [01/26] Re: wget으로 다른서버에있는 디렉토리를 가져오려고합니다.
    [01/25] wget으로 다른서버에있는 디렉토리를 가져오려고합니다.
    [01/11] 특정 안드로이드 WebView 버전에서 SSL 문제 (WebView 버그)
    [08/01] DNS forwarder (전달자) 서버를 통해서 쿼리하면 역방향을 받아오질 못합니다.
    [05/16] (주)후이즈 시스템엔지니어 (경력자) 모집
    [02/15] [AWS] Cloudfront edge 확인하기
    [01/20] Mobile Service/eCommerce 기업에서 Server / Java / PHP 개발자 구인
      New!   최근에 등록한 페이지
      KiCad EDA Suite project (Free/Libre/Open-Source EDA Suite) (CAD)
      오픈캐스케이드 캐드 (OpenCASCADE CAD)
      QCad for Windows --- GNU GPL (Free Software)
      The Hello World Collection
      IPMI를 활용한 리눅스 서버관리
      DNS 설정 검사
      nagiosgraph 설치 방법
      Slony-I 설치 방법 (postgresql replication tool)
      Qmail기반의 Anti spam 시스템 구축하기
      clusterssh

    [ 함께하는 사이트 ]




    운영진 : 좋은진호(truefeel), 야수(yasu), 범냉이, sCag
    2003년 8월 4일~