setting, git, shell etc

expect

qkqhxla1 2017. 7. 14. 16:01

맥이나 리눅스로 작업을 하다 보면 회사등에서 ssh를 이용해서 서버로 접속하는 경우가 많다.

 

나같은 경우 종종 프로그램이 잘 도는지 특정 서버로 접속을 해야 하는데, 이 과정이 너무 번거롭다.

 

ssh로 0번 서버에 접속 후, 다시 거기서 1번 서버로 접속 후, 다시 거기서 2번 서버로 접속하고, 그 이후에 특정 계정으로 로그인을 한 다음 작업을 시작한다.

 

종종 작업을 위해 접속하는 날도 있지만 단순히 모니터링을 위해 들어가는 날은 저 일련의 과정이 너무 귀찮다. ssh를 하나하나 치는것도 일이지만 서버 주소가 많다보니 기억을 잘 못해서 매번 페이지에서 찾아서 들어가기 때문이다.

 

그래서 인터넷에서 자동화 스크립트를 찾아봤다. 자동적으로 ssh로 0번서버, 1번서버, 2번서버로 접속후 특정 계정으로 로그인해주는 스크립트를 짰다.

 

expect라는것을 이용했다.

 

변수를 설정할수도 있고, 내가 이 값을 보냈을때 어떤 값이 오는지 정규식으로 예측가능하고, 값을 보낼 수도 있다.(끝에\r을 붙여준다.)

#!/usr/bin/expect -f

# 화면 재조정을 위해 넣어줘야 하는 부분
trap {
 set rows [stty rows]
 set cols [stty columns]
 stty rows $rows columns $cols < $spawn_out(slave,name)
} WINCH

# 변수 설정.
# id. set 으로 변수 설정이 가능하다.
set myaccount_id "아이디"
# ldap pw
set myaccount_pw "비밀번호"
set s_pw "서버비밀번호"
set awsgateway "$myaccount_id@서버 주소"
set after_ssh_connect "*?assword:"

# gateway접속
spawn ssh $awsgateway
expect $after_ssh_connect
send "$myaccount_pw\r"
expect "*\\$"

# 0번서버 접속
send "ssh 0번서버아이피\r"
expect $after_ssh_connect
send "$myaccount_pw\r"
expect "*\\$"

# 특정 계정으로 로그인 후 특정 디렉터리로.
send "su 로그인할 계정\r"
expect $after_ssh_connect
send "계정의 비밀번호\r"
expect "*\\$"
send "cd 특정 디렉터리\r"
expect "*\\$"
send "cd 특정 디렉터리2\r"
interact


expect로 서버들을 들어가서 docker ps결과를 가져오는 예제.
get_info.sh

#!/usr/bin/expect -f

# 화면 재조정을 위해 넣어줘야 하는 부분
trap {
 set rows [stty rows]
 set cols [stty columns]
 stty rows $rows columns $cols < $spawn_out(slave,name)
} WINCH

set host [lindex $argv 0];  # 인자로 받은 호스트를 사용한다.
if { $host == "" } {  # 없으면 종료시킴.
  send_user "input ip address\n"
  exit 1
}
set myaccount_id ""
set myaccount_pw ""
set aws_coupang_pw ""
set awsgateway "$myaccount_id@게이트웨이"
set after_ssh_connect "*?assword:"
set yes_or_no "*(yes/no)?"

# ssh gateway접속
spawn ssh $awsgateway
expect $after_ssh_connect
send "$myaccount_pw\r"
expect "*\\$"

send "ssh $host\r"
expect $yes_or_no
send "yes\r"
expect $after_ssh_connect
send "$myaccount_pw\r"
expect "*\\$"
send "sudo su coupang\r"
expect "*\\$"
send "export LC_ALL=\"en_US.UTF-8\"\r"
expect "*\\$"
send "docker ps | grep -e item -e delete\r"
expect "*\\$"
send "\r"

python.

import os
import subprocess
ip_list = ['10.1.2.3', '10.2.3.4', '10.3.4.5',]

for ip in ip_list:
    result = os.popen('./get_info.sh {}'.format(ip)).read()
    print(ip, '=', result[result.find('docker ps'):])