02. 셸이란 무엇인가
1. 셸(Shell)이란?
사용자와 리눅스 커널 사이에서 명령어를 해석하고 전달하는 인터페이스 프로그램
셸의 역할
┌─────────────────────────────────────────────────────────────────┐
│ 셸의 동작 과정 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 사용자 │
│ │ │
│ │ ① "date" 입력 + Enter │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 셸 (Shell) │ │
│ │ ② 입력받은 문자열 분석 │ │
│ │ ③ "date" 명령어 위치 탐색 (/bin/date) │ │
│ │ ④ 커널에게 명령어 실행 요청 │ │
│ └───────────────────────────┬─────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 커널 (Kernel) │ │
│ │ ⑤ 명령어 프로세스 생성 및 실행 │ │
│ │ ⑥ 실행 결과 반환 │ │
│ └───────────────────────────┬─────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 셸 (Shell) │ │
│ │ ⑦ 결과를 화면에 출력 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 사용자 화면: "2024년 12월 28일 토요일 오후 3시 30분 00초 KST" │
│ │
└─────────────────────────────────────────────────────────────────┘셸의 주요 기능
| 기능 | 설명 | 예시 |
|---|---|---|
| 명령어 해석 | 사용자 입력을 분석하고 실행 | ls -la 파싱 |
| 프로그램 실행 | 커널에 프로그램 실행 요청 | 명령어 → 프로세스 |
| 입출력 리다이렉션 | 입출력 방향 변경 | >, <, >> |
| 파이프라인 | 명령어 출력을 다른 명령어 입력으로 연결 | ls | grep txt |
| 환경 변수 관리 | 시스템/사용자 변수 설정 | $PATH, $HOME |
| 스크립트 실행 | 명령어 파일 순차 실행 | .sh 파일 |
| 작업 제어 | 백그라운드/포그라운드 작업 관리 | &, jobs, fg |
2. 셸과 커널의 분리
왜 분리되어 있을까?
┌─────────────────────────────────────────────────────────────────┐
│ 셸과 커널 분리의 이점 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ 셸 (교체 가능) │ │ 커널 (핵심 유지) │ │
│ ├──────────────────┤ ├──────────────────┤ │
│ │ • bash │ │ │ │
│ │ • zsh ←───── │ ────→ │ 리눅스 커널 │ │
│ │ • fish │ 인터 │ │ │
│ │ • tcsh │ 페이스 │ │ │
│ └──────────────────┘ └──────────────────┘ │
│ │
│ [이점 1] 셸만 교체하여 다른 사용 경험 가능 │
│ [이점 2] 셸 오류가 커널에 영향 주지 않음 (시스템 안정성) │
│ [이점 3] 다른 OS(FreeBSD, Solaris)에서도 같은 셸 사용 가능 │
│ [이점 4] 사용자별로 다른 셸 선택 가능 │
│ │
└─────────────────────────────────────────────────────────────────┘셸 이름의 유래
Shell(껍데기): 커널(핵심)을 감싸고 보호하는 껍질
┌─────────────────────────────┐
│ │
│ ┌───────────────────┐ │
│ │ │ │
│ │ 커널 │ │ ← Shell (껍데기)
│ │ (Kernel) │ │ 사용자와 커널 사이
│ │ 핵심 │ │ 중재자 역할
│ │ │ │
│ └───────────────────┘ │
│ │
└─────────────────────────────┘3. 프롬프트 (Prompt)
셸이 사용자에게 명령어 입력을 기다리고 있음을 나타내는 표시
프롬프트 구조
# 일반 사용자 프롬프트 예시
user@hostname:~/Documents$
│ │ │ │
│ │ │ └── $ : 일반 사용자 표시
│ │ └── 현재 디렉토리 (~ = 홈 디렉토리)
│ └── 호스트명 (컴퓨터 이름)
└── 사용자명
# 루트 사용자 프롬프트 예시
root@hostname:/etc#
│
└── # : 루트(관리자) 표시프롬프트 기호
| 기호 | 의미 | 권한 수준 |
|---|---|---|
$ | 일반 사용자 | 제한된 권한 |
# | 루트(슈퍼유저) | 모든 권한 |
% | C셸 계열 일반 사용자 | 제한된 권한 |
프롬프트 환경변수
# 현재 프롬프트 설정 확인
$ echo $PS1
\u@\h:\w\$
# 프롬프트 변수 의미
# \u : 사용자명
# \h : 호스트명 (첫 번째 점까지)
# \H : 전체 호스트명
# \w : 현재 작업 디렉토리 (전체 경로)
# \W : 현재 작업 디렉토리 (마지막 디렉토리만)
# \d : 날짜
# \t : 시간 (24시간 형식)
# \$ : 일반 사용자는 $, 루트는 #
# \n : 줄바꿈프롬프트 커스터마이징 예시
# 시간 추가
$ export PS1="[\t] \u@\h:\w\$ "
[14:30:45] user@host:~$
# 색상 추가 (녹색 사용자명, 파란색 경로)
$ export PS1="\[\033[32m\]\u\[\033[0m\]@\h:\[\033[34m\]\w\[\033[0m\]\$ "
# 간단한 프롬프트
$ export PS1="\W \$ "
Documents $
# 영구 적용하려면 ~/.bashrc에 추가
$ echo 'export PS1="[\t] \u@\h:\w\$ "' >> ~/.bashrc4. 로그인 셸과 비로그인 셸
로그인 셸
사용자가 시스템에 로그인할 때 자동으로 시작되는 첫 번째 셸
# 로그인 셸 확인
$ echo $SHELL
/bin/bash
# 현재 셸이 로그인 셸인지 확인
$ echo $0
-bash # 앞에 '-'가 있으면 로그인 셸
# 사용자별 로그인 셸 확인
$ cat /etc/passwd | grep username
username:x:1000:1000::/home/username:/bin/bash
└── 로그인 셸비로그인 셸
로그인 후 추가로 시작한 셸 (터미널 열기, 셸 명령어 실행 등)
# 비로그인 셸 시작
$ bash # 새로운 bash 시작
$ sh # sh 시작
# 셸 중첩 상태
login → bash (로그인 셸)
└→ sh (비로그인 셸)
└→ bash (비로그인 셸)
# 비로그인 셸 종료
$ exit # 현재 셸 종료 (이전 셸로 돌아감)
# logout은 로그인 셸에서만 동작
$ logout
bash: logout: not login shell: use `exit'셸 설정 파일
┌─────────────────────────────────────────────────────────────────┐
│ 셸 설정 파일 로딩 순서 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 로그인 셸 시작 시: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ /etc/profile (시스템 전체 설정) │ │
│ │ ↓ │ │
│ │ ~/.bash_profile (개인 설정, 우선순위 1) │ │
│ │ 또는 ~/.bash_login (없으면 이것) │ │
│ │ 또는 ~/.profile (없으면 이것) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 비로그인 셸 시작 시: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ ~/.bashrc (개인 설정) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 로그아웃 시: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ ~/.bash_logout (정리 작업) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘설정 파일 용도
| 파일 | 용도 | 예시 설정 |
|---|---|---|
/etc/profile | 시스템 전체 환경변수 | PATH 기본값 |
~/.bash_profile | 로그인 시 개인 설정 | 환경변수 export |
~/.bashrc | 셸 시작마다 실행 | alias, 프롬프트, 함수 |
~/.bash_logout | 로그아웃 시 실행 | 임시 파일 정리 |
5. 대화형 vs 셸 스크립트
대화형(Interactive) 모드
사용자가 명령어를 입력하고 결과를 즉시 확인하는 방식
$ date
2024년 12월 28일 토요일 오후 3시 30분 00초 KST
$ pwd
/home/user
$ ls
Documents Downloads Pictures셸 스크립트
실행할 명령어들을 파일에 미리 작성하여 자동 실행하는 방식
#!/bin/bash
# backup.sh - 간단한 백업 스크립트
# 변수 설정
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d)
SOURCE="/home/user/Documents"
# 백업 실행
echo "백업 시작: $SOURCE → $BACKUP_DIR"
tar -czf "$BACKUP_DIR/backup_$DATE.tar.gz" "$SOURCE"
echo "백업 완료!"# 스크립트 실행 권한 부여
$ chmod +x backup.sh
# 스크립트 실행 방법
$ ./backup.sh
$ bash backup.sh
$ source backup.sh셸 스크립트의 장점
┌─────────────────────────────────────────────────────────────────┐
│ 셸 스크립트 활용 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ [자동화] │
│ • 반복 작업 자동 실행 (백업, 로그 정리, 배포) │
│ • cron과 연동하여 예약 작업 │
│ │
│ [재사용] │
│ • 복잡한 명령어 조합을 저장 │
│ • 팀원과 공유하여 일관된 작업 수행 │
│ │
│ [문서화] │
│ • 작업 절차가 코드로 기록됨 │
│ • 주석으로 설명 추가 가능 │
│ │
│ [리눅스 철학] │
│ "작은 프로그램을 조합해 복잡한 처리를 수행한다" │
│ │
└─────────────────────────────────────────────────────────────────┘6. 셸의 종류
셸 계보
1971 Thompson Shell
│
▼
1977 Bourne Shell (sh)
│
┌──────────────────┼──────────────────┐
│ │ │
▼ ▼ ▼
1978 C Shell 1983 Korn Shell 1989 Bash
(csh) (ksh) (Bourne Again)
│ │
▼ │
1983 tcsh │
│ │
└────────────────────────────────────┤
│
1990 zsh ┘
2005 fish주요 셸 비교
| 셸 | 전체 이름 | 특징 | 스크립트 적합성 |
|---|---|---|---|
| sh | Bourne Shell | 최초의 Unix 셸, 기본적 기능 | 높음 (표준) |
| bash | Bourne Again Shell | sh 호환 + 확장 기능, 리눅스 기본 | 높음 |
| csh | C Shell | C언어 문법, 대화형 편리 | 낮음 |
| tcsh | TENEX C Shell | csh 개선판, 자동완성 | 낮음 |
| ksh | Korn Shell | sh + csh 장점 결합 | 높음 |
| zsh | Z Shell | bash + tcsh + 독자 기능 | 높음 |
| fish | Friendly Interactive Shell | 사용자 친화적, 구문 강조 | 중간 |
셸별 상세 비교
┌─────────────────────────────────────────────────────────────────┐
│ 셸 기능 비교표 │
├──────────┬──────┬──────┬──────┬──────┬──────┬──────────────────┤
│ 기능 │ sh │ bash │ csh │ zsh │ fish │ 설명 │
├──────────┼──────┼──────┼──────┼──────┼──────┼──────────────────┤
│ Tab 완성 │ ✗ │ ✓ │ ✓ │ ✓✓✓ │ ✓✓✓ │ 명령어/경로 자동완성│
│ 히스토리 │ ✗ │ ✓ │ ✓ │ ✓ │ ✓ │ 이전 명령어 검색 │
│ 에일리어스│ ✗ │ ✓ │ ✓ │ ✓ │ ✓ │ 명령어 별칭 │
│ 작업 제어 │ ✗ │ ✓ │ ✓ │ ✓ │ ✓ │ bg, fg, jobs │
│ 구문 강조 │ ✗ │ ✗ │ ✗ │ 플러그인│ ✓ │ 입력 시 색상 │
│ 자동 제안 │ ✗ │ ✗ │ ✗ │ 플러그인│ ✓ │ 히스토리 기반 제안 │
│ sh 호환 │ ✓ │ ✓ │ ✗ │ ✓ │ ✗ │ sh 스크립트 실행 │
│ 확장성 │ 낮음 │ 중간 │ 낮음 │ 높음 │ 중간 │ 플러그인/테마 │
├──────────┴──────┴──────┴──────┴──────┴──────┴──────────────────┤
│ ✓✓✓ = 매우 강력 ✓ = 지원 ✗ = 미지원 │
└─────────────────────────────────────────────────────────────────┘bash를 추천하는 이유
┌─────────────────────────────────────────────────────────────────┐
│ bash 선택 이유 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. 대부분의 리눅스 배포판 기본 셸 │
│ └── 별도 설치 없이 바로 사용 가능 │
│ │
│ 2. sh(본 셸)와 호환 │
│ └── 기존 sh 스크립트 그대로 실행 가능 │
│ │
│ 3. 대화형 + 스크립트 양쪽에 적합 │
│ └── 하나만 배워도 두 가지 용도로 활용 │
│ │
│ 4. 다양한 OS에서 사용 가능 │
│ └── Linux, macOS, Windows(WSL), FreeBSD, Solaris │
│ │
│ 5. 풍부한 문서와 커뮤니티 │
│ └── 문제 해결 정보 찾기 쉬움 │
│ │
└─────────────────────────────────────────────────────────────────┘7. 셸 전환하기
일시적 셸 전환
# 현재 셸 확인
$ echo $SHELL
/bin/bash
# 다른 셸로 전환 (중첩 실행)
$ sh
$
# sh 프롬프트로 변경됨
# 다시 bash 실행 (sh 위에 중첩)
$ bash
user@host:~$
# 현재 셸 스택
# bash (로그인 셸)
# └── sh (비로그인 셸)
# └── bash (비로그인 셸) ← 현재 위치
# 셸 종료
$ exit # bash 종료 → sh로 돌아감
$ exit # sh 종료 → 로그인 bash로 돌아감영구적 셸 변경
# 사용 가능한 셸 목록 확인
$ cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/bash
/bin/zsh
/usr/bin/zsh
/usr/bin/fish
# 로그인 셸 변경 (재로그인 필요)
$ chsh -s /bin/zsh
Password:
Shell changed.
# 또는 root 권한으로 다른 사용자 셸 변경
$ sudo chsh -s /bin/zsh username8. 터미널 에뮬레이터
터미널이란?
원래는 입출력 전용 하드웨어 장치. 현재는 이를 소프트웨어로 구현한 터미널 에뮬레이터를 의미
┌─────────────────────────────────────────────────────────────────┐
│ 터미널과 셸의 관계 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 터미널 에뮬레이터 (Terminal) │ │
│ │ │ │
│ │ ┌───────────────────────────────────────────────────┐ │ │
│ │ │ 화면 │ │ │
│ │ │ user@host:~$ ls -la │ │ │
│ │ │ total 32 │ │ │
│ │ │ drwxr-xr-x 4 user user 4096 Dec 28 15:30 . │ │ │
│ │ │ drwxr-xr-x 3 root root 4096 Dec 28 10:00 .. │ │ │
│ │ │ -rw-r--r-- 1 user user 220 Dec 28 10:00 .bashrc │ │ │
│ │ │ user@host:~$ _ │ │ │
│ │ └───────────────────────────────────────────────────┘ │ │
│ │ ↑↓ 입출력 전달 │ │
│ └──────────────────────────┬──────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 셸 (bash) │ │
│ │ 명령어 해석/실행 │ │
│ └─────────────────┘ │
│ │
│ [터미널]: 화면 표시, 키보드 입력 전달 (입출력 담당) │
│ [셸]: 명령어 해석, 커널과 통신 (처리 담당) │
│ │
└─────────────────────────────────────────────────────────────────┘주요 터미널 에뮬레이터
| OS | 터미널 에뮬레이터 | 특징 |
|---|---|---|
| Windows | Windows Terminal | MS 공식, 탭 지원, WSL 연동 |
| PuTTY | 가벼움, SSH 클라이언트 | |
| MobaXterm | 다기능, X11 포워딩 | |
| macOS | Terminal.app | 기본 내장 |
| iTerm2 | 분할 화면, 강력한 기능 | |
| Linux | GNOME Terminal | GNOME 기본 |
| Konsole | KDE 기본 | |
| Alacritty | GPU 가속, 빠름 | |
| Terminator | 화면 분할 |
터미널 vs 콘솔 vs 셸
| 용어 | 의미 |
|---|---|
| 터미널 | 입출력 인터페이스 (에뮬레이터) |
| 콘솔 | 물리적 터미널, 시스템에 직접 연결된 입출력 장치 |
| 셸 | 명령어 해석기 프로그램 |
| TTY | TeleTYpewriter, 가상 터미널 장치 |
9. 셸 편의 기능
히스토리 (History)
# 명령어 히스토리 보기
$ history
501 ls -la
502 cd /var/log
503 tail -f syslog
504 history
# 특정 번호의 명령어 실행
$ !503 # 503번 명령어 재실행
# 마지막 명령어 재실행
$ !!
# 특정 문자열로 시작하는 마지막 명령어
$ !tail # tail로 시작하는 마지막 명령어
# 히스토리 검색 (Ctrl + R)
(reverse-i-search)`tail': tail -f syslog
# 히스토리 파일 위치
$ echo $HISTFILE
/home/user/.bash_history
# 히스토리 크기 설정 (~/.bashrc)
export HISTSIZE=10000 # 메모리에 저장할 개수
export HISTFILESIZE=20000 # 파일에 저장할 개수자동 완성 (Tab Completion)
# 명령어 완성
$ sys<Tab>
systemctl systemd-analyze systemd-escape ...
# 파일/디렉토리 완성
$ cd /ho<Tab>
$ cd /home/
# 여러 후보가 있으면 Tab 두 번
$ cd /home/<Tab><Tab>
user1/ user2/ user3/
# 옵션 완성 (bash-completion 패키지)
$ git ch<Tab>
checkout cherry cherry-pick단축키
┌─────────────────────────────────────────────────────────────────┐
│ bash 필수 단축키 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ [커서 이동] │
│ Ctrl + A 줄 맨 앞으로 │
│ Ctrl + E 줄 맨 끝으로 │
│ Ctrl + ←/→ 단어 단위 이동 (Alt + B/F) │
│ │
│ [편집] │
│ Ctrl + U 커서 앞 전체 삭제 │
│ Ctrl + K 커서 뒤 전체 삭제 │
│ Ctrl + W 커서 앞 단어 삭제 │
│ Ctrl + Y 삭제한 내용 붙여넣기 │
│ │
│ [제어] │
│ Ctrl + C 현재 명령 중단 (SIGINT) │
│ Ctrl + Z 현재 명령 일시정지 (백그라운드로) │
│ Ctrl + D EOF / 셸 종료 │
│ Ctrl + L 화면 지우기 (clear) │
│ │
│ [히스토리] │
│ Ctrl + R 히스토리 역방향 검색 │
│ Ctrl + P 이전 명령어 (↑ 키) │
│ Ctrl + N 다음 명령어 (↓ 키) │
│ │
└─────────────────────────────────────────────────────────────────┘Alias (별칭)
# 별칭 설정
$ alias ll='ls -la'
$ alias cls='clear'
$ alias ..='cd ..'
$ alias ...='cd ../..'
# 별칭 확인
$ alias
alias ll='ls -la'
alias cls='clear'
# 별칭 삭제
$ unalias ll
# 영구 저장 (~/.bashrc에 추가)
$ echo "alias ll='ls -la'" >> ~/.bashrc
$ source ~/.bashrc # 즉시 적용10. 환경 변수
환경 변수란?
셸과 프로그램이 참조하는 시스템 설정값을 저장하는 변수
# 환경 변수 확인
$ env # 모든 환경 변수
$ printenv # 모든 환경 변수
$ echo $PATH # 특정 변수 값
# 주요 환경 변수
$ echo $HOME # 홈 디렉토리
/home/user
$ echo $USER # 현재 사용자
user
$ echo $SHELL # 로그인 셸
/bin/bash
$ echo $PATH # 명령어 검색 경로
/usr/local/bin:/usr/bin:/bin
$ echo $PWD # 현재 디렉토리
/home/user환경 변수 설정
# 셸 변수 설정 (현재 셸에서만 유효)
$ MY_VAR="hello"
$ echo $MY_VAR
hello
# 환경 변수로 내보내기 (자식 프로세스에도 전달)
$ export MY_VAR="hello"
# 한 줄로 설정 + 내보내기
$ export NEW_VAR="world"
# 영구 설정 (~/.bashrc 또는 ~/.bash_profile)
$ echo 'export MY_VAR="hello"' >> ~/.bashrc
# PATH에 디렉토리 추가
$ export PATH="$PATH:/home/user/bin"주요 환경 변수 정리
| 변수 | 설명 | 예시 값 |
|---|---|---|
HOME | 홈 디렉토리 | /home/user |
USER | 현재 사용자명 | user |
SHELL | 로그인 셸 | /bin/bash |
PATH | 명령어 검색 경로 | /usr/bin:/bin |
PWD | 현재 작업 디렉토리 | /home/user |
LANG | 시스템 언어 설정 | ko_KR.UTF-8 |
TERM | 터미널 타입 | xterm-256color |
EDITOR | 기본 편집기 | vim |
PS1 | 프롬프트 형식 | \u@\h:\w\$ |
요약
| 개념 | 핵심 |
|---|---|
| 셸 | 사용자-커널 인터페이스, 명령어 해석기 |
| 커널 분리 이유 | 유연성, 안정성, 이식성 |
| 프롬프트 | 셸의 입력 대기 표시 ($ 일반, # 루트) |
| 로그인 셸 | 로그인 시 시작되는 첫 셸 |
| 셸 스크립트 | 명령어 자동화 파일 |
| bash | 리눅스 기본 셸, sh 호환, 가장 범용적 |
| 터미널 | 입출력 담당 (에뮬레이터) |
| 환경 변수 | 시스템/셸 설정값 ($PATH, $HOME 등) |
빠른 참조
# 셸 정보
echo $SHELL # 로그인 셸
echo $0 # 현재 셸
cat /etc/shells # 사용 가능한 셸
# 셸 전환
bash / sh / zsh # 일시 전환
chsh -s /bin/zsh # 영구 변경
# 설정 파일
~/.bashrc # bash 설정 (비로그인)
~/.bash_profile # bash 설정 (로그인)
# 편의 기능
history # 명령어 히스토리
Ctrl + R # 히스토리 검색
Tab # 자동 완성
alias name='cmd' # 별칭 설정