새 리눅스 환경을 받을 때마다 반복하는 쉘 설정을 모았다. /bin/sh가 기대와 다르게 동작해서 당황하는 지점, 기본 쉘을 바꿨는데 안 바뀐 것처럼 보이는 지점, zsh로 넘어갈 때 챙길 것, 그리고 ls 색상 설정까지 매번 다시 찾아보던 것들을 한 곳에 정리한다.
/bin/sh는 bash가 아니다
우분투에서 /bin/sh는 bash가 아니라 dash를 가리킨다.
ls -al /bin/sh
# /bin/sh -> dashUbuntu 위키의 DashAsBinSh 문서는 그 이유로 두 가지를 든다. 하나는 속도다: “bash는 대화형 사용에 적합한 훌륭한 쉘이지만, dash에 비해 크고 시작·동작이 느리다.” 다른 하나는 POSIX 준수다: Debian 정책상 /bin/sh를 인터프리터로 지정한 스크립트는 POSIX 기능만 써야 한다.
문제는 #!/bin/sh 셔뱅을 달아 놓고 bash 문법을 쓰는 스크립트다. 실행은 되지만 dash가 그 문법을 이해하지 못해 조용히 다르게 동작한다. 대표적인 예가 [ 안의 == 비교다. bash에서는 되지만 POSIX test는 =만 인정한다.
echo 'if [ "a" == "a" ]; then echo ok; fi' > /tmp/t.sh
bash /tmp/t.sh # ok
dash /tmp/t.sh # /tmp/t.sh: 1: [: a: unexpected operatordash는 에러만 찍고 스크립트를 죽이지 않는다. if 조건이 그냥 거짓으로 처리되고 스크립트는 계속 실행되니, 원인을 찾기가 더 까다롭다. 같은 문서가 드는 다른 예로 source 대신 .을 써야 하는 것, 배열 변수를 쓸 수 없는 것도 있다.
결론: /bin/sh를 바꾸지 말고 셔뱅을 고친다. 정말 bash 문법이 필요한 스크립트라면 셔뱅을 #!/bin/bash로 명시하면 된다.
dpkg-reconfigure dash와 chsh는 다른 것
둘은 서로 다른 쉘을 바꾼다.
sudo dpkg-reconfigure dash # /bin/sh를 바꾼다 (dash <-> bash)
chsh -s $(which bash) # 로그인 쉘을 바꾼다터미널을 열었을 때 뜨는 “내 기본 쉘”을 바꾸고 싶다면 대부분 원하는 건 후자, chsh다. dpkg-reconfigure dash는 스크립트 실행에 쓰이는 /bin/sh만 바꿀 뿐, 로그인 쉘에는 영향이 없다.
chsh로 바꾼 로그인 쉘은 바로 적용되지 않는다. passwd(5)에 따르면 로그인 쉘 필드는 “로그인할 때 실행할 프로그램”이고, chsh(1)은 이 필드를 고치는 명령일 뿐이다. 즉 이미 열려 있는 터미널 세션에는 반영되지 않고, 다음 로그인부터 적용된다. 바꾼 직후 새 터미널을 열어도 그대로면 당황하지 말고 로그아웃 후 재로그인(또는 재부팅)하면 된다.
zsh와 oh-my-zsh
sudo apt install zsh
chsh -s $(which zsh)역시 로그인 쉘이므로 재로그인이 필요하다.
oh-my-zsh는 공식 설치 스크립트로 넣는다.
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"oh-my-zsh 저장소 문서에 따르면 이 스크립트는 기존 ~/.zshrc를 지우지 않고 ~/.zshrc.pre-oh-my-zsh로 이름을 바꿔 남긴 뒤 그 자리에 새 ~/.zshrc를 놓는다. 커스텀 설정이 있는 상태에서 curl | sh를 돌리기 전에 알아 둘 사실이다. 필요한 설정은 설치 후 백업 파일에서 새 .zshrc로 옮기면 된다.
자주 쓰는 alias 하나:
alias ll="ls -alhtr"ls 색상
터미널에서 ls 출력에 색상을 입히는 설정이다. 셸 프로파일(.bash_profile, .zprofile 등)에 넣는다.
export CLICOLOR=1
export LSCOLORS=Ehfxcxdxbxegedabagacad이 방식은 BSD 계열
ls(macOS 기본 터미널)용이다.GNU/Linux의 기본
ls(coreutils)는CLICOLOR/LSCOLORS를 무시하고, 대신ls --color옵션과LS_COLORS(+dircolors)를 사용한다. 즉 순수 리눅스라면 아래 “GNU/Linux에서는” 항목을 참고한다.
CLICOLOR=1
ls가 색상을 자동으로 출력하도록 켜는 스위치다. (0 또는 미설정이면 색상 없음)
LSCOLORS의 구조
LSCOLORS는 22글자 = 11쌍으로 이루어진다. 각 쌍은 [글자색][배경색] 순서이고, 11개의 쌍은 정해진 파일 종류 순서를 나타낸다.
Eh fx cx dx bx eg ed ab ag ac ad
│ │ │ │ │ │ │ │ │ │ └ 기타 쓰기 가능 디렉토리(스티키 비트 없음)
│ │ │ │ │ │ │ │ │ └─── 기타 쓰기 가능 디렉토리(스티키 비트)
│ │ │ │ │ │ │ │ └────── setgid 실행 파일
│ │ │ │ │ │ │ └───────── setuid 실행 파일
│ │ │ │ │ │ └──────────── 문자 장치(character special)
│ │ │ │ │ └─────────────── 블록 장치(block special)
│ │ │ │ └────────────────── 실행 파일(executable)
│ │ │ └───────────────────── 파이프(pipe/FIFO)
│ │ └──────────────────────── 소켓(socket)
│ └─────────────────────────── 심볼릭 링크(symbolic link)
└────────────────────────────── 디렉토리(directory)
색상 코드 (한 글자)
| 글자 | 색 | 글자 | 색 |
|---|---|---|---|
a | 검정(black) | b | 빨강(red) |
c | 초록(green) | d | 갈색/노랑(brown) |
e | 파랑(blue) | f | 자홍(magenta) |
g | 청록(cyan) | h | 밝은 회색(light grey) |
x | 기본색(default) |
- 대문자(
A~H) = 해당 색의 굵게/밝게(bold) 버전. 예:E= 굵은 파랑. - 배경색 자리에
x를 쓰면 터미널 기본 배경을 사용한다.
이 설정값 해석 — Ehfxcxdxbxegedabagacad
| 쌍 | 대상 | 글자색 | 배경색 |
|---|---|---|---|
Eh | 디렉토리 | 굵은 파랑(E) | 밝은 회색(h) |
fx | 심볼릭 링크 | 자홍(f) | 기본 |
cx | 소켓 | 초록(c) | 기본 |
dx | 파이프 | 갈색(d) | 기본 |
bx | 실행 파일 | 빨강(b) | 기본 |
eg | 블록 장치 | 파랑(e) | 청록(g) |
ed | 문자 장치 | 파랑(e) | 갈색(d) |
ab | setuid 실행 | 검정(a) | 빨강(b) |
ag | setgid 실행 | 검정(a) | 청록(g) |
ac | 스티키 쓰기 디렉토리 | 검정(a) | 초록(c) |
ad | 쓰기 디렉토리(스티키 없음) | 검정(a) | 갈색(d) |
기본값은
exfxcxdxbxegedabagacad이며, 이 설정은 첫 쌍만ex(파랑 글자·기본 배경) →Eh(굵은 파랑 글자·밝은 회색 배경)로 바꿔 디렉토리를 더 눈에 띄게 한 것이다.
GNU/Linux에서는
리눅스 기본 ls는 아래처럼 쓴다.
alias ls='ls --color=auto'
# 색 규칙은 LS_COLORS로 지정하며, dircolors로 생성/커스터마이즈
eval "$(dircolors -b)"참고
- DashAsBinSh — Ubuntu가
/bin/sh로 dash를 쓰는 이유(속도, POSIX 준수)와 대표적인 bashism 목록을 확인했다. - ohmyzsh/ohmyzsh — 설치 스크립트가 기존
~/.zshrc를.zshrc.pre-oh-my-zsh로 백업한다는 동작을 확인했다. - chsh(1), passwd(5) — chsh가 바꾸는 로그인 쉘 필드가 “로그인할 때 실행할 프로그램”이라 다음 로그인부터 적용된다는 점을 확인했다.