English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

expect 명령어를 사용하여 Shell 자동화 상호작용 방법 설명

배경

리눅스 스크립트에서는 많은 상황에서 원격 작업이 수행됩니다. 예를 들어 원격 로그인 ssh, 원격 복사 scp, 파일 전송 sftp 등입니다. 이러한 명령어들은 모두 보안 비밀번호 입력에 관련이 있으며, 명령어를 일반적으로 사용할 때는 비밀번호를 수동으로 입력하고 보안 인증을 받아야 합니다. 원격 작업을 자동화하기 위해 expect 기능을 활용할 수 있습니다.

expect는 무료 프로그래밍 툴 언어로, 자동 및 상호작용 작업을 통한 통신을 수행하고, 인간의 개입 없이도 사용할 수 있습니다. expect는 지속적으로 발전하고 있으며, 시간이 지남에 따라 기능이 더욱 강화되어, 시스템 관리자의 강력한 도구로 자리 잡고 있습니다. expect는 Tcl 프로그래밍 언어의 지원이 필요하며, 시스템에서 expect를 실행하려면 먼저 Tcl을 설치해야 합니다.

expect 설치

expect는 Tcl 기반으로 만들어졌기 때문에, expect를 설치하기 전에 먼저 Tcl을 설치해야 합니다.

(1) Tcl 설치

홈페이지: http://www.tcl.tk

다운로드 주소: http://www.tcl.tk/소프트웨어/tcltk/downloadnow84.tml

1. 소스 코드 패키지 다운로드

wget http://nchc.dl.sourceforge.net/sourceforge/tcl/tcl8.4.11-src.tar.gz 

2. 소스 코드 패키지 압축 해제

tar xfvz tcl8.4.11-src.tar.gz 

3. 설치 구성

cd tcl8.4.11/unix 
./configure --prefix=/usr/tcl --enable-shared 
make 
make install 

주의:

1、설치가 완료되면, tcl 소스 코드의 루트 디렉토리에 진입하여 unix 하위 디렉토리의 tclUnixPort.h를 generic 디렉토리로 복사합니다.

2、expect 설치 과정에서도 사용할 필요가 있으므로, tcl 소스 코드를 잠시 제거하지 마세요.

(2) expect 설치 (Tcl 라이브러리 필요)

홈페이지: http://expect.nist.gov/

1. 소스 코드 패키지 다운로드

wget http://sourceforge.net/프로젝트/expect/파일/Expect/5.45/expect5.45.tar.gz/download 

2. 소스 코드 패키지 압축 해제

tar xzvf expect5.45.tar.gz 

3. 설치 구성

cd expect5.45 
./configure --prefix=/usr/expect --with-tcl=/usr/tcl/lib --with-tclinclude=../tcl8.4.11/generic 
make 
make install 
ln -s /usr/tcl/bin/expect /usr/expect/bin/expect 

expect

expect의 핵심은 spawn, expect, send, set입니다.

spawn 실행할 명령 호출

  • expect 명령 표시 정보가 나타나기를 기다립니다. 즉, 사용자가 입력한 표시를 잡습니다:
  • send 필요한 상호작용 값 전송, 사용자가 수동으로 입력한 내용을 대체합니다
  • set 변수 값 설정
  • interact 실행이 완료되면 상호작용 상태를 유지하고, 제어권을 컨솔에 넘겨주면, 이때부터 수동으로操作할 수 있습니다. 이 문장이 없으면 로그인이 완료되면 로그아웃되고, 원격 터미널에 남지 않습니다.
  • expect eof은 반드시 추가해야 합니다. spawn과 일치하며 터미널 출력 정보가 종료됨을 의미합니다. if...endif과 유사합니다

expect 스크립트는 interact나 expect eof로 끝내야 합니다. 자동화 작업을 수행할 때는 일반적으로 expect eof만 충분합니다.

기타 설정

  • expect은 무한기간으로 설정되어 timeout이 설정되지 않습니다 set timeout -1
  • expect 설정 300 초 초과 시, 설정된 timeout300 expect 내용이 나타나지 않으면 set timeout을 종료합니다 300

expect 작성 문법

expect는 tcl 문법을 사용합니다

  • Tcl 명령어는 공백으로 구분된 단어로 구성됩니다. 첫 번째 단어는 명령어 이름이고, 나머지는 명령어 파라미터입니다
    cmd arg arg arg
  • $ 기호는 변수의 값을 의미합니다. 이 예제에서는 변수 이름이 foo입니다.
    $foo
  • 괄호는 내장 명령어를 실행합니다. 예를 들어, 명령어의 결과를 다른 명령어의 파라미터로 전달하려면 이 기호를 사용합니다
    [cmd arg]
  • 쌍따옴표는 단어 그룹을 명령어의 하나의 파라미터로 표시합니다. "$" 기호와 괄호는 쌍따옴표 내에서 해석됩니다
    "some stuff"
  • 대괄호는 단어 그룹을 명령어의 하나의 파라미터로 표시합니다. 하지만, 대괄호 내의 다른 기호는 해석되지 않습니다
    {some stuff}
  • 백슬래시 기호는 특수 기호를 인용하는 데 사용됩니다. 예를 들어: n은 줄바꿈을 의미합니다. 백슬래시 기호는 "$" 기호, 인용 기호, 괄호, 중괄호의 특수 의미를 해제하기도 합니다

예제

login.exp는 원격 로그인에 사용되며, 빠른 사용 방법: login.exp "exclude" "${remote_ip}" "${remote_user}" "${remote_passwd}" "${remote_command}"

#!/usr/bin/expect -f
##########################################################
# SSH를 통해 로그인하고 명령어 실행
# 파라미터:1.Use_Type [check/execute]
#  2.SSHServerIp
#  3.SSHUser
#  4.SSHPassword
#  5.CommandList [명령어 사이에 ;로 구분]
# 반환 값:
#  0 성공
#  1 파라미터 개수가 올바르지 않습니다
#  2 SSH 서버 서비스가 열려 있지 않습니다
#  3 SSH 사용자 비밀번호가 정확하지 않습니다
#  4 SSH 서버 연결 시간 초과
##########################################################
proc usage {} {}
 regsub ".*/" $::argv0 "" name
 send_user "Usage:\n"
 send_user " $name Use_Type SSHServerIp SSHUser SSHPassword CommandList\n"
 exit 1
} 
## 파라미터 개수�断정
if {[llength $argv] != 5}
 usage
}
#변수 값을 설정합니다
set Use_Type [lindex $argv 0]
set SSHServerIp [lindex $argv 1]
set SSHUser [lindex $argv 2]
set SSHPassword [lindex $argv 3]
set CommandList [lindex $argv 4]
#spawn ping ${SSHServerIp} -w 5
#expect {
# -nocase -re ""100% 패킷 손실" {
#  send_error "Ping ${SSHServerIp}는 접근할 수 없습니다. IP 주소를 확인하십시오.\n"
#  exit 1
# }
#}
set timeout 360
set resssh 0
#ssh 연결할 때 yes를 입력하는지 여부를 표시하는 변수 정의
set inputYes 0
set ok_string LOGIN_SUCCESS
if {$Use_Type=="check"} {
 #ssh 연결을 활성화하려면 필요한 경우 yes를 입력하십시오. inputYes를 설정하십시오1، 그렇지 않으면 ssh 비밀번호를 입력하십시오
 spawn ssh ${SSHUser}@${SSHServerIp} "echo $ok_string"
} else {   
 spawn ssh ${SSHUser}@${SSHServerIp} "$CommandList"
}
expect {
 -nocase -re "yes"/no" {
  send -- "yes\n"
  set inputYes 1
 }
 -nocase -re "assword: " {
  send -- "${SSHPassword}\n"
  set resssh 1
 }
 #-nocase -re "마지막 로그인: " { 
 #  send -- "${CommandList}\n"
 #}
 $ok_string {}
 -nocase -re "연결 거부"
  send_error "SSH 서비스 ${SSHServerIp}에서 활성화되지 않음.\n"
  exit 2
 }
 timeout {}}}
  send_error "Connect to SSH server ${SSHUser}@${SSHServerIp} timeout(10s).\n"
  exit 4
 }
}
#yes를 확인하면, ssh 비밀번호를 입력합니다.
if {$inputYes==1}
 expect {
  -nocase -re "assword: " {
   send -- "${SSHPassword}\n"
   set resssh 1
  }
 }
}
#try again 또는 password: 표시가 나타나면, 입력한 사용자 비밀번호가 오류입니다. 즉시 종료됩니다.
if {$resssh==1}
 expect {
  -nocase -re "try again" {
   send_error "SSH user:${SSHUser} passwd error.\n"
   exit 3
  }
  -nocase -re "assword:" {
   send_error "SSH user:${SSHUser} passwd error.\n"
   exit 3
  }
  eof {}
 }
}
send_error -- "$expect_out(buffer)"
#-nocase -re "No such user" {
#  send_error "No such user.\n"
#  exit 5
# }
#exit

정리

이 글의 모든 내용이 끝납니다. 이 글의 내용이 여러분의 학습이나 업무에 도움이 되길 바랍니다. 의문이 있으시면 댓글을 통해 교류해 주시기 바랍니다. 감사합니다.呐喊 튜토리얼에 대한 여러분의 지원에 감사합니다.

고지: 본 문서의 내용은 인터넷에서 가져왔으며, 저작권은 원작자에게 있으며, 인터넷 사용자가 자발적으로 기여하고 업로드한 내용입니다. 사이트는 소유권을 가지지 않으며, 인공 편집을 하지 않았으며, 관련 법적 책임도 부담하지 않습니다. 저작권 침해가 의심되는 내용이 있을 경우, 이메일을 notice#w로 보내 주시기 바랍니다.3codebox.com(보고할 때는 #을 @으로 변경하십시오. 관련 증거를 제공하시면, 확인된 후 해당 사이트는 즉시 저작권 침해 내용을 삭제합니다.

추천 합니다