02. 셸이란 무엇인가

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\$ "' >> ~/.bashrc

4. 로그인 셸과 비로그인 셸

로그인 셸

사용자가 시스템에 로그인할 때 자동으로 시작되는 첫 번째 셸

# 로그인 셸 확인
$ 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

주요 셸 비교

전체 이름특징스크립트 적합성
shBourne Shell최초의 Unix 셸, 기본적 기능높음 (표준)
bashBourne Again Shellsh 호환 + 확장 기능, 리눅스 기본높음
cshC ShellC언어 문법, 대화형 편리낮음
tcshTENEX C Shellcsh 개선판, 자동완성낮음
kshKorn Shellsh + csh 장점 결합높음
zshZ Shellbash + tcsh + 독자 기능높음
fishFriendly 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 username

8. 터미널 에뮬레이터

터미널이란?

원래는 입출력 전용 하드웨어 장치. 현재는 이를 소프트웨어로 구현한 터미널 에뮬레이터를 의미

┌─────────────────────────────────────────────────────────────────┐
│                    터미널과 셸의 관계                             │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│   ┌─────────────────────────────────────────────────────────┐   │
│   │              터미널 에뮬레이터 (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터미널 에뮬레이터특징
WindowsWindows TerminalMS 공식, 탭 지원, WSL 연동
PuTTY가벼움, SSH 클라이언트
MobaXterm다기능, X11 포워딩
macOSTerminal.app기본 내장
iTerm2분할 화면, 강력한 기능
LinuxGNOME TerminalGNOME 기본
KonsoleKDE 기본
AlacrittyGPU 가속, 빠름
Terminator화면 분할

터미널 vs 콘솔 vs 셸

용어의미
터미널입출력 인터페이스 (에뮬레이터)
콘솔물리적 터미널, 시스템에 직접 연결된 입출력 장치
명령어 해석기 프로그램
TTYTeleTYpewriter, 가상 터미널 장치

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'     # 별칭 설정