본문 바로가기
OS/Linux

Mac에서 쉘 스크립트로 다중 서버에 같은 명령 내리기

by supdev 2018. 7. 4.



AWS에 여러 서버를 활용해야 하는 프로젝트 중 여러 서버에 같은 명령을 내려야하는 경우가 생겼습니다.

Window 환경에서는 SuperPUTTY라는 프로그램이 이 역할을 수행할 수 있지만 맥에는 SuperPUTTY가 없기에...


구글링을 통해 자료를 찾던 중 맥에서는 스크립트를 짜서 해야한다는 글을 발견했고,

쉘 스크립트라는 것을 경험하기에 이르렀습니다.


먼저 위 기능을 구현하기 위해서는 터미널에서 암호를 입력하지 않고 미리 등록해두어야 하기에 SSHPass라는 툴을 사용했습니다.

ssh-keygen을 통해 암호화 키를 받아두는 방법도 있지만 심플하게 암호를 파일에 넣어두는 것으로 대체했습니다.



1. SSHPass 설치

SSHPass를 설치하는 명령은 아래와 같습니다.


on Ubuntu

$ apt-get install sshpass

on Mac

$ brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb


sshpass를 통해 해당 서버에 접속하며 접속 명령어 뒤에 아래와 같이 수행할 명령어를 넣어주면 서버에 접속 후 명령을 바로 실행합니다.

$ sshpass -p password ssh username@127.0.0.1 -p port "cd /some/direcory; rm somefile"


2. Shell 파일 작성

vi 나 nano 같은 텍스트 에디터를 활용해 작성하여 filename.sh 과 같은 형식으로 저장하면 됩니다.

#!/bin/sh

LIST_PATH="/.../multi_command/server.list"      # 접속할 서버 리스트 파일 경로
LOG_PATH="/.../multi_command.log"               # 명령 실행 로그 파일 경로
COMMAND="some; command"                         # 동시에 내릴 명령어

echo "--- Multi Command Shell Start ---"
echo "[COMMAND] ""\"${COMMAND}\""

while read LINE;                                # 서버 리스트 파일을 한 줄씩 읽어 처리
do
  echo $LINE" connecting..."
  $LINE "$COMMAND" < /dev/null >> $LOG_PATH &   # 수행된 결과를 로그 파일에 기록
  if [ "$?" -eq 0 ]; then
    echo "success"
  else
    echo "fail"
  fi
done < $LIST_PATH
echo "--- Multi Command Shell Finish ---"


3. 파일 정보 리스트파일 작성

server.list 파일의 경우 아래와 같이 서버 정보를 한 줄씩 나열하면 됩니다.

sshpass -p password1 ssh username1@127.0.0.1 -p port
sshpass -p password2 ssh username2@127.0.0.2 -p port
...


4-1. 실행 권한 주기

그냥 실행하게 되면 "Permission error"가 발생합니다. 실행 전 chmod 명령으로 권한을 줍니다.

$ chmod +x shell_name


4-2. 실행

쉘을 실행하면 순차적으로 파일 리스트에 기재된 서버에 접속하여 해당 명령어를 실행하게 됩니다.

$ ./shell_name


위 쉘 파일을 통해 많은 서버에 동시 명령을 내려야할 때 유용하게 사용했었습니다.

수행할 명령어를 쉘 파일에 직접 입력했지만 때에 따라 파라미터로 받아 사용할 수도 있을 것 같습니다.