유닉스 커맨드와 shell을 이용한 검은 화면에서의 작업은 터미널이 익숙하지 않은 사람들에게 개발자에 대한 환상을 심어주는 요소입니다. 하지만 정작 프론트엔드 개발자들 사이에서는 터미널 작업이 백엔드 개발자와 SRE 엔지니어의 전유물로 여겨지는 것을 보곤 합니다. 이 시리즈에서 프론트엔드 개발자에게 기본적인 터미널 문해력이 어떻게 도움이 될 수 있는지 살펴보고, 실제 업무에 적용할 때 도움이 될 자료를 소개하고자 합니다.
첫번째 글에서는 제가 업무를 하며 터미널을 적극적으로 사용하려 노력하면서 느낀 터미널에서의 업무 자동화가 갖는 의의를 공유하고 기본적인 셸 명령어를 소개합니다.
터미널을 쓴다는 것
소프트웨어 작성은 인간 노동을 컴퓨터 계산으로 대체하는 작업이기도 합니다. 하지만 프로그래밍과 그 과정에 필요한 업무들은 여전히 인간 노동을 필요로 하지요. 업무를 자동화하기 위해 FaaS, 브라우저 익스텐션, bot 작성 등 여러 툴을 사용하거나 제작할 수도 있습니다. 그런데 종종 이런 툴을 사용하는 것이 오버킬이거나, 사람이 해도 될 것 같은 작업을 만나곤 합니다.
- 새로 참여하게 된 웹프로젝트의 z-index 정리
- 아직 분석 툴을 연동시키지 않은 nginx 서버의 로그에서 에러 코드 검출
- 스타일 파일 분리를 위한 모든 Vue SFC 컴포넌트의 style 태그 제거
- 복수의 (n > 5) 리포에 pre-commit 정책을 적용시키기 위한 husky 설치
이렇게 업무 중 쉽지만 반복적인 일을 작업들이 생기면, 본격적인 툴을 사용하거나 제작하기에는 부담이 되지만, 사람이 하면 소모적인 단순 반복 작업이 됩니다. 이런 회색 영역에 속하는 업무는 대체로 터미널 명령어들이 큰 도움이 될 수 있습니다.
물론 터미널에서의 처리가 근본적인 문제 해결이 될 수 없습니다. 대다수의 일들은 시간이 걸리더라도 뿌리가 되는 원인을 찾아 해결하는 것이 옳습니다. 터미널을 쓴다는 것은 가용한 인적 자원이 한정되어 있을 때, 사람 대신 컴퓨터에게 시키는 일의 범위가 확장되는 데 의미가 있습니다.
왜 컴퓨터에게 일을 시켜야 하는가
그럴 리는 없겠지만 일할 사람과 시간이 많다고 해도, 컴퓨터에게 시킬 수 있는 일은 컴퓨터에게 시키는 게 좋습니다. 그 이유는 다음과 같습니다:
- 정확성
- 사람은 실수하지만, 컴퓨터는 실수하지 않습니다.
- 재사용성
- 유용한 스크립트를 작성했다면, 비슷한 작업을 할 때 재사용할 수 있습니다
- 재현가능성 (reproducibility)
- 사람이 한 일은 사람이 검증할 수밖에 없습니다.
- 반복 작업을 리뷰 받는 pr의 경우, 리뷰어는 작업자의 변경 작업을 그대로 따라가며 검증해야 합니다.
- ex) "'.vue' 파일을 돌며 style 태그를 하나씩 삭제했습니다"
→ 리뷰어도 모든 '.vue' 파일을 점검하며 변경 사항이 모두 반영됐는지 확인해야 합니다.
- diff 하나 하나 살피면서 변경사항이 제대로 이루어졌는지 확인하는 것은 매우 고된 일이고, 철저한 검증이 이루어진 후 승인이 됐다고 생각하는 것은 지나친 낙관입니다.
- 스크립트 작성 시, 리뷰어는 diff를 하나하나 눈으로 확인하지 않고, 논리를 검증할 수 있게 됩니다.
- 업무의 게임화 (gamification)
- 단순 반복은 개발자의 사기를 저하시킵니다.
- DX가 낮아지면 UX 또한 낮아집니다.
- 필요한 경우, 개발자는 스크립트 작성을 통해 '단순 반복 작업'을 '논리 구성 작업'으로 전환시킬 수 있어야 합니다.
- 이 과정은 마치 퍼즐 풀기와 같아서 재밌습니다.
"이펙티브 엔지니어"에서의 셸 명령어
효율적인 개발자가 되기 위한 지침서인 "이펙티브 엔지니어"의 저자는 책에서 '레버리지'라는 용어를 소개합니다. '레버리지'는 ROI의 다른 이름으로 "생산한 효과 / 투자한 시간"으로 정리됩니다. 책의 주된 메시지는 "레버리지가 높은 활동에 집중하라"로, 이를 위한 실행방침을 제시합니다. 그 중에 터미널 사용과 관련 있는 내용을 발췌합니다.
프로그래밍 환경을 마스터하라
- 좋아하는 텍스트 에디터와 IDE를 능숙하게 다뤄라
- 생산적이고 수준 높은 프로그래밍 언어를 적어도 하나는 배워라
- 유닉스나 윈도우의 셸 명령(shell command)에 익숙해져라
- 기본 유닉스 도구로 데이터를 조작하고 처리하면 작업을 완료하는 시간을 몇 분에서 몇 초로 줄일 수 있다.
- grep, sort, uniq, wc, awk, sed, xargs, find 등 기본 명령어를 배워라
- 마우스보다 키보드를 우선 사용해라
- 수동 작업 흐름을 자동화하라
- "셸 스크립트를 사용하든 브라우저 확장 기능을 사용하든, 자동화하는 기술을 개발하는 데는 시간이 든다. 그러나 기술을 익히는 경험이 늘어나고 실력이 발전할수록 이러한 기술을 숙달하는 데 드는 비용은 점점 줄어든다."
- 인터랙티브 인터프리터(interactive interpreter)로 아이디어를 테스트하라
- 변경사항과 관련 있는 단위 테스트를 빠르고 쉽게 실행할 수 있게 하라
적극적인 터미널 사용에 앞서
터미널과 친해지기 위해 이미 여러 번 시도해봤지만 실패를 맛보았거나, 처음으로 터미널을 적극적으로 사용하고자 하는 분들께 다음의 마인드셋을 제안드립니다:
- 사전에 모든 명령어를 학습하는 것은 어렵습니다. 점진적인 학습을 추천합니다.
- 어떤 명령어들이 있는지 알아두기만 하고, 각 명령어 학습은 해당 기능이 필요할 때 하는 것이 좋습니다.
- "이 작업은 'a', 'b' 명령어를 사용하면 쉽게 할 수 있겠는걸?"
→ 'a', 'b'에 필요한 기능 있는지 추가 탐색 후 적용 시도
- 일이 되게 하는 게 우선입니다.
- 학습과 시행착오에 너무 많은 시간이 들고 있다면, 우선 사람이 직접 해결하는 편이 낫습니다.
- 반복되는 시행착오는 '학습 시간 + 스크립팅 시간'과 '사람이 직접 할 때의 시간' 사이에 저울질을 더 정확하게 해줍니다.
- "만약 수동으로 두 번 이상으로 해야 하는 일이 생기면 세 번째에는 도구를 작성하라" _ 라피 크리코리안 (트위터의 플랫폼 엔지니어링 부사장) _ "이펙티브 엔지니어" 중 발췌
기초 명령어
man {command}
를 통해 보는 매뉴얼이 가장 정확합니다. 이 글에선 후에 추가적인 학습을 하기 위한 기본정보만 기재합니다.
grep
- ed라는 에디터의 후손.
- ed 명령어인 'g/re/p'에서 이름을 얻었습니다.
- 입력값에서 정규표현식 패턴에 매칭된 라인을 출력합니다.
- 사용 예시
- 유용한 플래그
- -E, --extended-regexp: 패턴을 확장된 정규표현식으로 인식하게 한다.
- -F, --fixed-strings: 패턴을 정규표현식이 아니라 고정 문자열로 인식하게 한다.
- -i, --ignore-case: 패턴의 대소문자 구별을 하지 않게 한다.
- -v, --invert-match: 패턴에 매칭되지 않은 라인을 출력한다.
- -o, --only-matching: 패턴에 매칭된 부분만 출력한다.
sort
uniq
- 입력값에서 연속으로 중복된 라인을 제거하여 유일(unique)하게 만듭니다.
- 유용한 플래그
- -c, --count: 중복된 라인 수를 함께 출력한다.
wc
- word count
- 원하는 단위로 입력 파일의 길이를 잽니다 (바이트, 단어, 줄)
- 유용한 플래그
- -l, --lines: newline 갯수를 센다.
awk
- 패턴 스캐닝과 텍스트 처리를 위한 하나의 언어입니다.
- 저자의 이름에서 이름을 얻었습니다: Alfred Aho, Peter Weinberger, Brian Kernighan.
- 유용한 플래그
sed
xargs
- extended arguments
- 다른 커맨드에 넘길 인자를 다른 파일에서 얻어올 수 있습니다.
- 유용한 플래그
- -t, --verbose: 커맨드 실행 전, 어떤 커맨드를 실행하는지 출력한다.
- -p, --interactive: 커맨드 실행 전, 커맨드 실행 여부를 묻는다.
- -n, --max-args: 한 커맨드 라인에 사용할 최대 인자 개수를 지정한다.
find
- 디렉토리 구조에서 파일을 찾는 방법입니다.
- 유용한 플래그
- -name: 매칭할 이름 패턴을 지정한다.
- -type: 탐색 대상이 되는 파일의 종류를 지정한다.
- f: regular file
- d: directory
watch
- 다른 명령어를 주기적으로 실행합니다.
- 유용한 플래그
- -n, --interval: 몇 초마다 반복할지 정한다.
time
추천 학습 자료