기본적인 셸 프로그래밍
프로그래밍을 하다 보면 반복되는 입출력을 줄이고 싶어지고, 자연스레 축약어, 단축명령어, 자동화 스크립트를 고민하기 시작한다. 회사에서 사용하는 대표적인 업무 툴 두개를 뽑자면 지라 애자일 보드와 깃이다. 일을 시작한지 4개월 쯤 됐을 때부터 가끔 나에게도 볼륨이 큰 업무들이 할당되었고, 나는 효율성을 높이기 위해 반복되는 작업들을 줄이는 일에 흥미가 생겼다. 지라에는 오토메이션 룰을 설정할 수 있고, 깃허브 등의 다른 툴들과도 웹훅을 주고받을 수 있다. 커밋을 올리면 태스크가 완료 처리되고, 하위 태스크들을 모두 완료처리하면 자동으로 상위 태스크를 완료 처리하는 룰을 만드는 것이 신기하고 재미있었다. (나는 무언가 자동으로 이루어지도록 스크립트를 만들고, 그대로 동작하는 걸 볼 때 여전히 항상 신기하다)
깃(git) 버전관리 프로그램의 경우, 기본적으로 약속된 터미널 명령어들이 있다. 기본적이고 대표적인 명령어들은 이런 것들이 있다.
git add . // 현재까지의 작업물을 스테이징 (확정)
git commit -m "blah blah" // 작업내용에 제목을 지어서 커밋 (수정내용 반영)
git push // 수정한 작업내용을 원격브랜치에 올리기
git reset HEAD^ // 스테이징 취소
git rebase [branch] // 특정 브랜치로 작업의 시작점을 변경
git rebase -i HEAD~n // n 개의 커밋 히스토리를 탐색 후 헤드 교체
(과거 이력을 수정하거나 삭제할때 사용한다)
이러한 명령어들을 별칭(alias)으로 줄여서 사용할 수 있다. 깃허브 설정파일에 미리 별칭을 등록해주면 되는데, 간단한 함수를 쓰고 싶다면 쉘 스크립트 문법을 사용해 구현하면 된다.
데이터를 저장하고 처리하는 물리적인 하드웨어 공간과 사용자 사이에는 운영체제라는, 사용자가 조작할 수 있는 인터페이스가 있다. 운영체제가 실행되기 위해서는 다른 소프트웨어들과 마찬가지로 메모리에 올라가야 하는데, 너무 크기 때문에 일부는 메모리에 항상 올라가 있고, 일부는 필요할 때만 올라간다. 경우에 따라서는 메모리에 상주해있는 부분만을 가리켜 운영체제 자체로 보기도 한다. 이 상주하는 부분을 커널이라고 한다. 커널은 운영체제의 핵심적인 부분으로, 컴퓨터의 보안과 자원관리를 담당한다.
사용자가 컴퓨터 전원을 켜고 운영체제를 실행시킨 후 커널에 접근하려면 쉘(Shell) 이라는 인터프리터를 사용해야 한다. 역사적으로 다양한 종류의 쉘들이 개발되어왔고, 현재는 bash 라는 이름의 쉘이 표준으로 채택되어 많은 운영체제의 기본 쉘로 사용된다. 쉘은 터미널이라는 프로그램을 통해 동작한다. 그러니까, 쉘에 명령어를 입력하고 싶다면 터미널 프로그램을 켜서 쉘 명령어를 입력하면 된다. 쉘은 터미널을 통해 입력받은 명령어를 커널로 전송하고, 다시 그 결과를 받아와서 터미널 창에 띄워준다. 또는 확장자 sh로 끝나는 파일을 만들어서 미리 스크립트를 적어주고 sh 라는 명령어로 실행하면 쉘이 그 스크립트에 적힌 명령을 커널에 전달해 결과를 출력한다.
깃 명령어의 별칭을 변경하기 위해서는 .gitconfig 파일에 단축어와 실제명령어를 매칭해서 적어주면 된다. .gitconfig 라는 파일은 git config 라는 명령어를 통해 설정할 수 있는 git의 속성들을 미리 저장해놓는 설정파일이다.
가령, git push 대신 git ps 를 쓰고 싶다면 .gitconfig 파일에 이렇게 적어주면 된다.
ps = push
그밖에 다른 명령어들의 별칭 지정은 이런 식으로 할 수 있다.
https://gist.github.com/yeonwooz/de1d82b24122e13b14e8189f7b7c43b4
그런데 깃 명령어 중에는 고정되지 않은 명령어도 있는데, 이건 어떤 명령어로 저장해두면 좋을까?
git rebase -i HEAD~5 // 최근 커밋 이력 5개 보기
자주 확인하는 이력 개수들을 개별적으로 미리 등록해놓기는 번거로운 것 같다. 원하는 커밋 이력 개수를 인자로 받아 git rebase -i HEAD~ 끝에 넣어주도록 하는 함수를 만들면 좋을 것 같다.
약간의 shell 문법(?)을 살펴보자.
#!/bin/bash : 스크립트를 실행할 기본 쉘을 지정. 쉘 스크립트 파일이라면, 첫줄에 무조건 포함되어야 함.
$0 : 스크립트 파일이 실행되는 프로그램의 이름이 포함된 첫 번째 문자열
$1, ...$N : n번째로 입력되는 매개변수
.gitconfig 파일에는 아쉽게도 매개변수를 받는 함수를 직접적으로 선언할 수는 없다. 그러나 함수를 만들고 실행하는 커맨드 자체를 스트링으로 지정해놓을 수는 있다.
rb = "!f() { git rebase -i HEAD~${1}; }; f"
! 를 통해 git 명령어임을 알려주고, 함수 구문을 만들고 (f() { git rebase -i HEAD~${1}; };) , 실행한다. (f)
프로그래밍 언어별로 기본적인 변수 생성과 함수 출력 정도는 할 줄 아는 것이 큰 자산이 되는 것 같다.
TMI.
gist 로 코드블록 삽입하는 방법을 알고 나니 정말 편하다!
Photo by Markus Spiske on Unsplash
참고자료
learning git branching : https://learngitbranching.js.org/?locale=ko
github cheat sheet : https://training.github.com/downloads/ko/github-git-cheat-sheet/
unix shell : https://www.tutorialspoint.com/unix/unix-what-is-shell.htm
커널 : https://ko.wikipedia.org/wiki/%EC%BB%A4%EB%84%90_(%EC%BB%B4%ED%93%A8%ED%8C%85)
쉘 스크립트 : https://en.wikipedia.org/wiki/Shell_script
스택오버 플로우 git alias 질의응답: https://stackoverflow.com/questions/50194720/git-rebase-zsh-shell-alias