지금 다니고 있는 회사는 출퇴근 시간이 유연하다보니 매일 출근 시간을 체크해야 퇴근 시간을 확인할 수 있다. (듣자하니 현재 쓰고있는 보안업체와 데이터를 연동하는 데에는 비용이 든다는 것 같다.) 그래서 매일 부팅 시간을 보고 퇴근 시간을 추측하는데, 슬랙이라면 이걸 해결해줄 수 있을 지도 모른다는 생각이 들었다.

하지만 나 쉘알못인데…


맥에서 부팅 시간 확인하기

터미널에 간단하게 last reboot 명령어를 치면 부팅 기록이 내림차순으로 출력된다.

last reboot


# reboot    ~                         Wed Mar  4 10:10
# reboot    ~                         Tue Mar  3 09:03
# reboot    ~                         Mon Mar  2 11:12
# reboot    ~                         Fri Feb 28 09:31
# reboot    ~                         Thu Feb 27 10:02
# reboot    ~                         Wed Feb 26 10:02
# reboot    ~                         Tue Feb 25 09:07
# reboot    ~                         Mon Feb 24 09:20
# ...


하지만 나에게 필요한 건 가장 최근의 기록이기 때문에 주로 이 명령어를 통해 집에 갈 시간을 확인한다.

last reboot | head -n 1


# reboot    ~                         Wed Mar  4 10:10


위와 같이 출력되는 정보 중에 부팅 시간, Wed Mar 4 10:10 을 Slack Bot 에게 보내는 것을 목표로 잡았다. 물론 시간 스케줄링을 하거나 평일에만 작동하는 등 조건을 두면 더 좋겠지만 일단 터미널 -> 슬랙으로 원하는 데이터를 보내는 과정이 선행되어야 하니 이 부분에 집중해보았다.



Shell Script

굳이 위키백과에서 정의를 가져오자면 ‘셀이나 명령 줄 인터프리터에서 돌아가도록 작성되었거나 한 운영 체제를 위해 쓰인 스크립트’ 라고 한다. 연속적으로 명령을 수행하기 위해 쓰인 명령어 조합 이라고 이해했다. 나는 맥이나 우분투 등에서 간단한 리눅스 명령어만 써봤기 때문에 문법을 조금 살펴보기로 했다.


sh 파일 생성

vim 같은거 쓰기 싫으니까 에디터를 통해 shell.sh 이라는 이름의 파일을 하나 만들었다. sh 파일은 #!/bin/sh와 함께 시작한다. 주석은 앞에 #을 붙여서 달고, 로그는 echo 명령어를 통해 출력할 수 있다. 문자열에 따옴표를 붙여도, 붙이지 않아도 되지만 가능하면 안전하게 따옴표를 붙이자.

새로운 거 배울 때에는 인사부터 하는 게 국룰.

#!/bin/sh
echo Hey
echo "Hi"


# Hey
# Hi


스크립트 실행

맥 터미널에서 shell.sh 파일을 실행했다. 파일 이름 앞에 ./ 를 붙인다.

./shell.sh


나는 zsh [경로] 명령어를 사용했다. (Bash를 쓴다면 bash [경로]를 사용한다.) zsh를 써서 /Users/yenachoi/dev 폴더에 있는 스크립트를 실행했다.

zsh /Users/yenachoi/dev/shell.sh


변수 선언

name="YENA" 형식으로 띄어쓰기 없이 써야 문법 오류가 발생하지 않는다. 위와 마찬가지로 문자열에 따옴표를 붙여도, 붙이지 않아도 둘 다 인식한다. 변수를 불러올 때에는 $name 와 같이 사용한다.

#!/bin/sh
name="YENA"
echo "$name likes black coffee"


# YENA likes black coffee


반복문

어디서 많이 본 듯한 느낌의 loop 문법.

for i in 1 2 3 4 5
do
  echo "print i : $i"
done


# print i : 1
# print i : 2
# print i : 3
# print i : 4
# print i : 5

또는

for i in {1..5}
do
  echo "print i : $i"
done


재미있는 건 in 와일드카드 *를 사용하면 디렉토리 내에 있는 파일을 차례로 프린트 해준다.

for i in *
do
  echo "print i : $i"
done


# print i : Applications
# print i : Desktop
# print i : Documents
# print i : Downloads
# print i : Library
# print i : Movies
...


함수

예상대로 함수를 사용하는 방법도 명료하고 간단했다.

myfunc()
{
    echo "When will Corona end?"
}

# Execute function
myfunc


# When will Corona end?



Slack Webhook 연동하기

슬랙 문서 중에 ‘Sending your first Slack message using Webhook’ 라는 제목을 가진 페이지가 있다. 구글에 터미널에서 슬랙으로 메세지 전달하는 법을 검색했는데 기특하게도 이 문서가 먼저 나와주었다. 슬랙 문서는 정말로 친절한 것 같다.

문서를 따라가면서 Create an App 페이지를 통해 특정 workplace에서 작동하는 앱을 만들 수 있다.



그리고 Add features and functionality 메뉴에서 Incoming Webhooks 에 새로운 Webhook 을 추가해준다.

Webhook은 우리가 전달하는 메세지를 슬랙 채널로 전달해 주는 중간 다리 역할을 수행한다. 채널을 선택하면 URL이 생성되는데, 이 URL로 json 형태의 메세지를 보낼 수 있다.


curl -X POST -H 'Content-type: application/json' --data '{"text":"Rock Yeah!"}' YOUR_WEBHOOK_URL


Slack 메세지 보내기

스크립트 문법 맛보기도 했고 웹훅 URL도 받았으니 메세지를 보내보자. mydate 변수에 last reboot 결과를 저장해야 했는데 이것부터 문법을 몰라 애먹었다.

var=$(function) 형식으로 함수에서 계산된 값을 저장할 수 있었다.

그리고, json 형식으로 사용하려니까 따옴표가 나를 엄청 힘들게 했다. 문자열에 따옴표를 써도 되고 안 써도 되니, 값이 엉망이 되어 제대로된 json 형식으로 서버 통신을 할 수가 없었다. ‘reboot ~ Wed Mar 4 10:10’ 이라는 문자열을 보내야 하는데, 이게 각각의 함수로 인식되어서 ‘reboot’ 함수를 실행할 권한이 없다고 하고 난리도 아니었다. json을 사용할 때에는 문자열의 따옴표와 형식에 주의하자.

여자저차 만들어진 코드는 이렇다.

#!/bin/sh
mydate=$(last reboot | head -n 1)

json="{\"text\": \"$mydate\"}"
echo "json : " $json

my_slack_webhook="https://hooks.slack.com/services/대충-내-웹훅-코드/"
curl -X POST -H 'Content-type: application/json' --data "$json" $my_slack_webhook


거의 이틀 삽질했는데, 몇 줄 안 돼서 더 억울하다. 이렇게 만들어진 shell script 를 실행하면 바로 슬랙 메세지가 온다! 마음의 병이 나았다.


더 가다듬은 결과는 Mac 터미널에서 Slack에 메세지 보내기(2)에서.


결론

삽질 + 블로그 글 쓰느라 늦게 자서 내일 출근은 10시 넘어서 할 것 같다…


References

  • https://ko.wikipedia.org/wiki/%EC%85%B8_%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8
  • https://www.shellscript.sh/