저번 시간에, default shell이 zsh 대신 bash로 설정되어 있는 문제를 맞닥뜨렸다.

중요한 게 있다. terminal 에서 중간에 설정을 바꿀 경우, 설정이 곧바로 적용되지 않는다. 설정은 쉘(shell)이 처음 load될 때에만 읽어들여지기 때문이다. 유저가 로그인 하면 쉘이 새로 생성되면서 load 된다. 그러면서 시스템 설정을 override 하기 때문에, 이미 쉘 설정이 load 가 된 상태에서 새로운 설정을 추가한 경우에는 load 될 기회가 없기 때문에 적용이 되지 않는 것이다. 그러므로 강제로 새로운 설정을 load 해야 한다!!! 강제로 새로운 설정 load를 하는 방법은 2가지가 있다. 설정이 적용되도록 하는 방법은,

  1. 설정이 바뀔 때마다 iterm 을 껐다가 다시 켠다. 쉘이 다시 로드되면서 새 설정이 적용된다.
  2. . ~/.zshrc 를 사용해 zsh 설정 파일을 강제로 불러와 실행한다.

설령 default shell 이 zsh라 하더라도, .zshrc가 바뀌면 두 방법 중 하나를 실행해야지만 바뀐 설정이 적용된다. 아무튼, 매번 번거롭게 zsh를 강제실행할 필요 없이 terminal 을 처음 실행할 때부터 default shell이 zsh로 실행되길 원하기 때문에 default shell 을 바꿔보도록 하겠다!

방법 자체는 간단하다. 코드 한 줄이면 된다.

sudo sh -c 'echo /usr/local/bin/zsh >> /etc/shells' && chsh -s /usr/local/bin/zsh

하지만 보시다시피 그 코드는 간단하지 않다…^^… 그래서 이제 이 코드를 하나하나 뜯어볼 것이다. 나와 우리 모두의 ‘이해에 기반한 암기’를 위해!

  • sudo : ‘su‘peruser ‘do’ 라는 뜻이다. 관리자 권한으로 실행한다는 뜻이다. 읽기전용 파일 수정도sudo와 함께라면 가능하다!
  • sh -c : ‘sh‘ell s’c‘ript. 이 다음으로 오는 코드를 shell 로 인식해 실행해달라는 뜻이다. command 뒤에 ‘-‘와 함께 붙는 알파벳은, 이 command 의 option 이다! 구글에 검색해보니 flag 라고 부르더라… 구글에서 데려온 영어 설명. sh calls the program sh as interpreter and the -c flag means execute the following command as interpreted by this program. sh -c 가 왜 필요할까??? sudo 명령어 뒤에 만일 sh -c 가 없다고 가정해보자. 그럼 sudo echo /usr/local/bin/zsh >> /etc/shells && ... 가 될 것이다. 이렇게 되면 sudo 가 실행하는 것이 기존에 따옴표 안에 있던 것 전부 (&& 이전까지) 가 아니라, echo /usr/local/bin/zsh 까지밖에 안 된다. 그냥 관리자 권한으로 zsh 경로를 echo 하고 끝나는 것이다.
  • echo : 파이썬의 print, javascript 의 console.log와 같은 기능을 하는 command 이다. bash나 C shells 에서 인자(argument)를 화면에 출력해주는 command 이다. 여기서 echo 가 왜 쓰였을까? 따옴표 안에 echo가 없다면 컴퓨터는 /user/local/bin/zsh를 command 로 받아들일 것이다. 그런데 이 경로는 실제로 zsh 프로그램이다. 그러니까 아마 컴퓨터는 zsh 를 command 로 받아들이고 실행할 것이다.
  • /user/local/bin/zsh : 내 zsh 가 들어있는 경로이다.
  • >> : 좌측에 있는 경로를 오른쪽에 있는 파일에 append 해준다는 뜻이다. 왜 이렇게 해야 할까 싶어서 etc 에 있는 shell 파일을 열어보니, 읽기 전용으로 되어 있었다. 읽기 전용 파일에 강제로 쓰이게 하기 위해서 » 를 쓴 걸까? 했는데 아니었다. 그건 sudo가 해주는 일이다….

열어보기 전까진 뭘 하는 파일인지 몰랐다. 이게 무슨 파일인줄 모르면 코드의 전반부가 존재하는 이유를 이해할 수 없다. 하나하나 내 손으로 뜯어보고 열어봐야 무엇인지 알 수 있고, 또 이해할 수 있다는 걸 명심하자.

  • /etc/shells : list of acceptable shells 를 관리하는 파일인 ‘shells’ 의 경로이다. 읽기 전용 파일인데, sudo 를 통해서 쓰고 지우기가 가능하다.
  • && : ‘and’를 의미한다.
  • chsh -s : chsh command 는 로그인 쉘(login shell), 즉 default shell 을 바꿔주는 command 이다. ‘ch‘ange ‘sh‘ell. 그리고 chsh 뒤에 -s가 붙으면, 로그인 쉘을 non interactive manner 로 바꿔준다. 간단히 말하면, 묻지 않고 바꾼다는 뜻이다. interactive manner 라는 것은, 바꿀지 안 바꿀지 물어본다는 건데, -s 없이 chsh 만 사용하게 되면 쉘을 변경할건지 말건지 물어보게 된다.

그러니까 결론적으로는, /usr/local/bin/zsh 코드에서 zsh 를 실행해버리는 게 아니라, zsh경로만 echo 한 다음, 그 경로를 sudo>> 를 통해 /etc/shells에 집어넣은 것이다. 여기까지가 acceptable shells 의 목록에 zsh 을 추가해주는 과정이었다! &&의 뒷쪽에서는 드디어 chsh -s 커맨드를 통해 login shell, 즉 default shell 을 바꿔준 것이다!

험난한 해석의 강을 건넜다… 혼자서 생각하는 과정은 많은 오류를 동반한다(예컨대, >> 가 읽기 전용 파일에 무언가를 강제로 쓰이게 하는 거라고 생각했던 점이라든지…). 설명을 듣고 나면 뭔가 이해는 했는데 아리송하다. 들은 설명을 정리하면서 적는 이러한 과정을 거쳐야지만, 정리하는 과정에서 “아, 이게 이런 뜻이었구나” 이해하는 부분도 생기고, 완벽하게 이해할 수 있다. 그런데 완벽하게 이해한 것 맞겠지…?