Linux

expect 명령어

현재 회사에서 사용중인 제품이 PC와 연결되어 있는데 제품을 사용자가 수동으로 전원을 끄지 않고 원격으로 끄는 방법에 대해 찾아 보는 중에 ssh로 이용하여 poweroff 명령어를 보내는 것으로 가능했지만 ssh 접속 시 나오는 문구에 대해 자동으로 처리하는 방법에 대해 막히게 되었다. 구글링 하던 중 입력을 자동으로 하게 해주는 exepct 명령어를 확인하게 되었다.

 

expect 

Linux manual page에 따르면 다음과 같이 설명한다. Expect 는 다른 대화형 프로그램과 "대화"하는 프로그램입니다.  사용자는 원할 때 직접 제어하고 상호 작용할 수 있습니다. 그런 다음 스크립트에 제어권을 반환합니다.

 

 

SSH 자동화

아래는 exepct를 사용하여 만든 원격종료 쉘 파일이다.

#!/usr/bin/expect

set USERNAME "user"
set IP "ip"
set PW "1"
set timeout 5
log_user 0

puts "
************************************
*                                  *
*  POWEROFF		                   * 
*                                  *
************************************
"

spawn ssh -t ${USERNAME}@${IP} sudo poweroff
expect {
    "(yes/no)?" {
        send "yes\n"
        exp_continue
    }
    "password:" {
        send "${PW}\n"
		exp_continue
    }
    "user:" {
        send "${PW}\n"
		exp_continue
    }
    "closed." {
	send_user "POWEROFF SUCCESS \n"
    }
}

 

위 코드에 대해 설명하자면 set의 경우에는 변수 선언과 같은 개념으로 생각하면 된다. USERNAME에 ssh에 접속할 username을 적어주고 IP에는 ssh에 접속할 IP 주소를 입력한다. PW에는 ssh에 user password를 적어주면 된다.

timeout의 경우에는 디폴트의 타임 아웃 시간을 지정한다. 지정하지 않은 경우 10초가 된다.

set USERNAME "user"
set IP "ip"
set PW "1"
set timeout 5

 

log_user의 경우에는 프로그램 실행 시 나오는 출력에 대한 설정이다. 기본적으로 stdout 표시하는데, stdout을 제외하려면 0으로 설정하면 된다.

 

puts는 보는 거와 같이 단순 출력을 위한 명령어다.

log_user 0

puts "
************************************
*                                  *
*  POWEROFF		                   * 
*                                  *
************************************
"

 

 

spawn은 expect내에서 프로세스를 생성하는 커맨드로 spawn 뒤에 원하는 명령어(ssh)를 입력해주면 된다.

spawn ssh -t ${USERNAME}@${IP} sudo poweroff

 

expect 뒤에 나오는 입력 문구가 하나라면 그냥 사용해도 무방하지만 여러 개의 입력 문구가 있다면, {} 감싸서 적어주면 된다. 아래는 ssh 실행 시 나오는 입력 문구인 (yes/no)?와 password: 그 다음 sudo 명령어 실행 시 나오는 user: 그리고 ssh 종료 시 나오는 closed. 네 개를 지정하고 있다. 

 

send는 입력 문구에 대한 값을 전달하는 명령어이다.

 

그 아래에 exp_continue는 expect가 return 되지 않고 계속 실행되도록 하는 명령어로 expect 명령어를 실행해도 expect로부터 벗어나지 않고 expect안에서의 처리를 계속하는 것이 가능하다.

 

send_user는 stdout을 원격지가 아닌 사용자에게 전송합니다.

expect {
    "(yes/no)?" {
        send "yes\n"
        exp_continue
    }
    "password:" {
        send "${PW}\n"
		exp_continue
    }
    "user:" {
        send "${PW}\n"
		exp_continue
    }
    "closed." {
	send_user "POWEROFF SUCCESS \n"
    }
}

 

 

 

Bash 쉘 파일로 자동화를 구성할 경우 expect 명령어 사용시 -c 옵션을 이용하여 " " 안에 자동화 코드를 넣어준다.

#!/bin/bash

USERNAME="USER"
IP="IP"
PW="1"

cat <<EOF
************************************
*                                  *
*  POWEROFF 		               *
*                                  *
************************************
EOF

expect -c "
set timeout 5
log_user 0

spawn ssh -t ${USERNAME}@${IP} sudo poweroff
expect {
    \"(yes/no)?\" {
    send \"yes\n\"
    exp_continue
    }
    \"password:\" {
    send \"${PW}\n\"
    exp_continue
    }
    \"user:\" {
    send \"${PW}\n\"
    exp_continue
    }
    \"closed.\" {
    send_user "POWEROFF SUCCESS \n"
    }
}
"

출처 :

https://engineer-mole.tistory.com/233

 

[Linux] expect를 이용한 Linux 커맨드 입력 자동화

Linux환경에서 어떤 패키지를 설치할 때 yes를 입력해야거나 선택지를 입력해야할 경우가 있는데, 이럴 때 그러한 입력을 자동화할 수 있는 것이 expect이다. expect란? Linux에서의 커맨드 대화를 자동

engineer-mole.tistory.com

https://linux.die.net/man/1/expect

 

'Linux' 카테고리의 다른 글

v4l2loopback  (0) 2024.01.21
Device Tree  (0) 2023.12.19
ubuntu 네트워크 장치 이름 변경  (0) 2023.07.16
PCIe ASPM Error  (0) 2023.07.02
i2c-tools  (0) 2023.01.28