리눅스마스터 2급 필기 09 — Shell (셸 종류·환경 설정 파일·변수·히스토리·별칭·프롬프트·리다이렉션) [2차 1과목 리눅스 운영 및 관리]
출제기준 2차 1과목: 리눅스 운영 및 관리 — Shell
기출 빈도 상위권(약 9%) 단원입니다.
셸 종류별 개발자, 설정 파일 4종, 변수, 리다이렉션이 핵심이에요!
셸이란? ⭐⭐⭐
리눅스는 하드웨어를 직접 제어하는 커널(Kernel)과, 사용자와 커널 사이의 접점인 셸(Shell)로 나뉩니다.
셸은 사용자가 입력한 명령어를 해석해 커널에 전달하고 결과를 돌려주는 명령어 해석기(Command Interpreter)입니다.
하드웨어와 사용자를 감싸는 껍데기라서 Shell이라고 부르고, 사용자 공간(User Space)의 가장 최전선에 위치합니다.
1 하드웨어 → 2 커널 → 3 셸 → 4 응용프로그램
셸의 동작 흐름 5단계
| 단계 | 내용 |
| ① 명령 입력 | 사용자가 ls 같은 명령 입력 |
| ② 해석 | 셸이 문법 분석, 내장/외장 명령 구분 |
| ③ 요청 전달 | 시스템 호출(System Call)로 커널에 요청 |
| ④ 하드웨어 제어 | 커널이 실제 하드웨어에 접근 |
| ⑤ 결과 출력 | 셸이 사람이 읽을 수 있는 텍스트로 변환해 출력 |
- 내장 명령: cd, echo, history 등 — 셸 자체에 포함
- 외장 명령: ls, cp 등 — /bin/ls 같은 별도 실행 파일 (
type 명령어로 구분) - 반복 작업 자동화를 위해 if문, for문 같은 프로그래밍 문법(셸 스크립트)도 제공합니다.
⭐ "사용자 공간의 가장 최전선에서 사용자와 직접 대면하는 프로그램은?" → 셸
셸의 종류 ⭐⭐⭐⭐⭐ (최고 빈출)
| 종류 | 경로 | 개발자 | 특징 |
| Bourne Shell | /bin/sh | 스티븐 본 | 유닉스 최초 셸(1977), 가볍고 빠르지만 히스토리·별칭 없음 |
| C Shell | /bin/csh | 빌 조이(UC 버클리) | C언어 유사 문법, 히스토리·별칭·작업 제어를 처음 도입 |
| Tcsh | /bin/tcsh | 켄 그리어 | csh 확장, 명령어 완성·편집 강화 |
| Korn Shell | /bin/ksh | 데이비드 콘 | Bourne 호환 + C Shell 편의 기능 모두 포함 |
| Bash | /bin/bash | 브라이언 폭스(GNU) | 리눅스 표준 셸, sh 호환, csh·ksh 장점 결합, 화살표 키 편집·강력한 히스토리 |
| Zsh | /bin/zsh | 폴 팔스타드 | bash·ksh 확장, 테마·플러그인 (macOS 기본 셸) |
💡 암기법: 본→sh, 조이→csh, 그리어→tcsh, 콘→ksh, 폭스→bash, 팔스타드→zsh.
bash는 "Bourne-Again(다시 태어난 본 셸)"이라는 말장난입니다.
⚠️ 함정 기출: "bash는 빌 조이가 GNU 프로젝트를 위해 개발했고 화살표 키 편집이 불가능하다" → 틀림.
bash는 브라이언 폭스가 개발했고 화살표 키 편집이 큰 장점입니다. 빌 조이는 csh 개발자입니다.
⭐ "유닉스 초기 셸로 가볍고 빠르지만 히스토리·별칭이 없는 셸은?" → Bourne Shell
⭐ "가장 먼저 등장한 셸은?" → Bourne Shell (1977)
셸 확인과 변경 ⭐⭐⭐⭐
셸 확인
| 방법 | 내용 |
echo $SHELL |
현재 로그인 셸 경로 확인 → /bin/bash |
grep 사용자 /etc/passwd |
7번째 필드가 로그인 셸 |
💡 $SHELL은 로그인 셸 경로이고, 지금 실제로 실행 중인 셸은 echo $0이나 ps -p $$로 확인합니다.
셸 변경
로그인 셸로 지정할 수 있는 셸은 /etc/shells에 등록된 것뿐입니다.
| 명령 | 옵션 | 내용 |
|---|---|---|
| 명령 | 옵션 | 내용 |
| chsh (change shell) | -s 셸경로 | 한 줄로 즉시 셸 변경 |
| -l | /etc/shells(사용 가능한 셸 목록) 출력 | |
| usermod | -s 셸경로 사용자 | root가 특정 사용자의 셸을 강제 변경 |
chsh -s /bin/sh test1 (사용자 본인이 변경)
usermod -s /bin/ksh user01 (root가 강제 변경)
변경 프로세스: ① 실행 → ② /etc/shells에서 유효성 검증(아니면 Error) → ③ /etc/passwd 7번째 필드 수정 → ④ 로그아웃 후 재로그인해야 적용
⭐ "사용 가능한 셸 목록이 기록된 파일은?" → /etc/shells
⭐ "root가 user01의 셸을 ksh로 강제 변경" → usermod -s /bin/ksh user01
⚠️ chsh -l은 셸 목록이며 사용자별 로그인 셸 확인이 아닙니다.
💡 /sbin/nologin은 대화형 로그인을 막는 '셸'입니다.
apache, mysql 같은 서비스 계정에 지정해 로그인을 차단하는 대표적인 보안 하드닝 기법입니다.
셸 환경 설정 파일 ⭐⭐⭐⭐⭐ (최다 출제)
사용자가 로그인하거나 새 셸을 실행할 때 환경 변수, 프롬프트, 별칭, 함수를 자동으로 정의해 주는 스크립트 파일입니다.
| 구분 | 파일 | 설명 |
| 전역 | /etc/profile | 시스템 전체 환경 변수·시작 프로그램 |
| 전역 | /etc/bashrc | 시스템 전체 별칭·함수 |
| 개인 | ~/.bash_profile | 사용자 전용 환경 변수(PATH 등) |
| 개인 | ~/.bashrc | 사용자 전용 별칭·함수 |
| 해제 | ~/.bash_logout | 로그아웃 시 실행할 명령 |
암기 규칙: profile 계열 = 환경 변수 / rc 계열 = 별칭·함수 / /etc/ = 전체 / ~/ = 개인
로그인 셸 vs 비로그인 셸
| 구분 | 상황 | 읽는 파일 |
| 로그인 셸 | 아이디·패스워드로 접속 | profile 계열 주도 |
| 비로그인 셸 | 로그인된 상태에서 새 터미널 창을 열거나 su(하이픈 없음)로 전환 | profile은 안 읽고 rc 계열(~/.bashrc) 중심 |
실제 읽는 순서 (RHEL 계열 bash)
로그인 셸: /etc/profile (→ /etc/profile.d/*.sh) → ~/.bash_profile
(없으면 ~/.bash_login → ~/.profile)
~/.bash_profile 안에서 ~/.bashrc 호출 → ~/.bashrc 안에서 /etc/bashrc 호출
로그아웃 시: ~/.bash_logout
비로그인 셸: ~/.bashrc (→ /etc/bashrc)
su -(하이픈 있음)는 로그인 셸이라 profile 계열까지 읽습니다. 05편의 su vs su -와 연결됩니다.- 설정 파일 수정 후 즉시 적용:
source ~/.bashrc(또는. ~/.bashrc) /etc/profile.d는 몇몇 응용프로그램의 시작 스크립트가 위치하는 디렉터리입니다.
⭐ "시스템 전체에 적용되어 모든 사용자에게 동일한 환경 변수·시작 프로그램을 설정하는 파일은?" → /etc/profile
⭐ "비로그인 셸의 특징은?" → 로그인 과정이 없어 ~/.bashrc 같은 rc 계열만 읽는다
⭐ "~/.bashrc에 설정하는 항목은?" → alias와 function
💡 별칭·함수는 부모 셸에서 설정해도 자식 셸로 상속되지 않기 때문에 셸이 시작될 때마다 읽는 .bashrc에 둡니다.
PATH는 환경 변수라 자식 프로세스에 상속되므로 .bash_profile이 적합합니다.
⚠️ 함정 기출: "~/.bash_login은 개인 사용자가 로그인할 때 수행하는 일반 설정 파일이다" → 틀린 설명 취급.
.bash_login은 .bash_profile이 없을 때만 읽는 대체 파일입니다.
셸 변수 ⭐⭐⭐⭐⭐
변수는 문자열·숫자·경로 등을 저장하고 참조하는 메모리 공간입니다.
| 구분 | 설명 | 적용 범위 |
| 지역 변수 | 현재 로그인한 셸에서만 유효 | 현재 셸 |
| 환경 변수 | 현재 셸 + 하위 프로세스에 상속 | 현재 + 하위 |
| 특수 변수 | 셸이 자체적으로 설정 | 시스템 전반 |
변수 설정 기본
| 내용 | 명령 | 주의 |
| 선언 / 호출 | VAR=value / $VAR |
= 앞뒤 공백 금지, 현재 셸만 |
| 환경 변수로 승격 | export VAR=value |
하위 프로세스까지 상속, 세션 종료 시 소멸 |
| 영구 저장 | vi ~/.bashrc |
재시작 후에도 유지 |
| 실행 경로 추가 | export PATH=$PATH:/dir |
기존 경로 뒤에 추가 |
관련 명령: env/printenv(환경 변수 목록), set(셸 변수·함수 전체), unset 변수(삭제), echo $변수(값 확인)
⭐ PATH 추가 기출: Bash에서 PATH에 /etc/kde를 추가하는 명령은?
→ PATH=$PATH:/etc/kde (또는 export PATH=$PATH:/etc/kde)
⚠️ export PATH=/etc/kde는 기존 값을 덮어써서 사라지게 하고, export $PATH=...는 문법 오류입니다.
미리 정의된 환경 변수 (암기)
| 변수 | 내용 |
| HOME | 홈 디렉터리 경로 |
| USER | 현재 사용자 이름 |
| HOSTNAME | 호스트 이름 |
| TERM | 터미널 종류(xterm, vt100) |
| TMOUT | 설정 시간(초) 동안 입력이 없으면 자동으로 셸 세션 종료 |
| EDITOR | 기본 텍스트 편집기 |
| PATH | 실행 파일을 찾는 디렉터리 경로 모음 |
| LANG | 기본 언어 |
| PWD | 현재 작업 디렉터리(cd 하면 값이 바뀜) |
| PS1 | 프롬프트 모양 |
| SHELL | 현재 셸 경로 |
⭐ "cd 명령의 수행 결과에 따라 값이 변하는 환경 변수는?" → PWD
특수 변수 (암기)
| 변수 | 내용 |
| $$ | 현재 셸의 PID |
| $? | 직전 명령의 종료 상태(0=성공, 그 외=실패) |
| $0 | 실행된 스크립트 이름 |
| $* | 스크립트로 전달된 모든 인자 |
| $! | 가장 최근 백그라운드 프로세스의 PID |
추가: $#(인자 개수), $@(모든 인자, 각각 별개로 취급), $1 $2 …(위치 매개변수)
💡 보안 점검 항목: /etc/profile에 TMOUT=600; export TMOUT로 유휴 세션을 자동 종료시키고, PATH에 .(현재 디렉터리)를 넣지 않는 것을 권고합니다(악성 파일 실행 방지).
히스토리(History) ⭐⭐⭐⭐
입력한 명령어를 저장해 두었다가 다시 불러 쓰는 기능입니다.
| 명령 | 내용 |
history |
지금까지 입력한 명령 목록(번호 포함) |
history 숫자 |
최근 N개만 출력 |
history -c |
현재 셸의 히스토리 모두 삭제 |
| 단축키 | 내용 |
| !! | 직전 명령 다시 실행 |
| !번호 | 해당 번호의 명령 실행 |
| !문자열 | 해당 문자열로 시작하는 가장 최근 명령 실행 |
| ↑ ↓ | 이전/다음 명령 |
| 변수 | 내용 |
| HISTSIZE | 메모리에 저장할 명령 개수(기본 1000) |
| HISTFILE | 히스토리 파일 경로(기본 ~/.bash_history) |
| HISTFILESIZE | 파일에 저장될 최대 명령 개수 |
⭐ "실행 후 저장되는 history 개수를 확인(설정)하는 환경 변수는?" → HISTSIZE
💡 히스토리는 로그아웃할 때 ~/.bash_history에 기록됩니다.
history -w는 즉시 파일 기록, history -d 번호는 특정 줄 삭제, Ctrl+R은 역방향 검색입니다.
history -c는 메모리만 지우므로 파일까지 지우려면 history -c && history -w가 필요합니다.
보안 감사에서 .bash_history는 중요한 증적입니다.
별칭(Alias) ⭐⭐⭐⭐
긴 명령어에 짧은 이름을 붙이는 기능입니다.
| 명령 | 내용 |
alias |
설정된 모든 별칭 출력 |
alias 이름='명령' |
별칭 설정 (예: alias ll='ls -alF') |
unalias 이름 |
별칭 해제 |
⭐ "ls에 설정된 alias를 해제하는 명령은?" → unalias ls
⚠️ alias -c는 없는 옵션이고, ualias는 없는 명령입니다.
💡 alias는 현재 셸에서만 유효하고 로그아웃하면 사라집니다.
영구 적용은 ~/.bashrc(개인) 또는 /etc/bashrc(전체)에 기록합니다.
프롬프트 설정 — PS1 ⭐⭐⭐⭐
터미널에서 커서 앞에 표시되는 [user@localhost ~]$가 프롬프트이고, 형태는 PS1 환경 변수에 저장됩니다.
확인은 echo $PS1 → [\u@\h \W]\$.
| 문자 | 의미 | 예 |
| \u | 사용자 이름 | root |
| \h | 호스트 이름(짧게) | localhost |
| \H | 전체 호스트 이름 | localhost.localdomain |
| \w | 전체 경로 | /usr/local/bin |
| \W | 현재 디렉터리명만 | bin |
| \t | 현재 시간 | 14:30:59 |
| \d | 현재 날짜 | Tue Feb 17 |
| ! | 히스토리 번호 | 105 |
| $ | 권한 표시 | #(root) / $(일반) |
⚠️ 대소문자 함정: \w(전체 경로) vs \W(디렉터리 이름만), \h(짧은 호스트) vs \H(전체 호스트).
변경 예: PS1='[\u@\h \w]\$ ' (영구 적용은 ~/.bashrc에 export PS1=...)
리다이렉션과 파이프 ⭐⭐⭐⭐⭐ (기출 단골)
교재의 셸 장에는 없지만 2차 기출에서 꾸준히 나오는 내용이라 보강합니다.
| 기호 | 의미 |
> |
표준 출력을 파일에 저장 (덮어쓰기) |
>> |
표준 출력을 파일 끝에 추가(Append) |
< |
파일로부터 표준 입력을 읽음 |
| (파이프) |
앞 명령의 표준 출력을 다음 명령의 표준 입력으로 연결 |
& |
명령을 백그라운드로 실행 |
# |
bash의 주석 시작 기호 |
2> |
표준 에러를 파일로 |
2>&1 |
에러를 표준 출력과 합침 |
/dev/null |
버려지는 장치(출력을 없앨 때) |
cat file > list (덮어쓰기)
cat file >> list (끝에 추가)
cat < ihd.txt | cat (입력 리다이렉션 + 파이프)
sleep 100 & (백그라운드 실행)
find / -perm -4000 2>/dev/null (에러 메시지 버리기)
| 파일 치환 문자 | 의미 |
? |
임의의 한 글자 |
* |
임의의 0개 이상 문자 |
⚠️ 함정 기출: ">>는 파일로부터 표준 입력을 읽는 입력 리다이렉션이다" → 틀림. >>는 출력 추가이고, 입력은 <입니다.
⭐ "명령어를 백그라운드로 실행하려면 뒤에 붙이는 문자는?" → &
⭐ "bash에서 주석의 시작은?" → #
기출 문제 Q&A
Q. 사용자 공간의 가장 최전선에서 사용자와 직접 대면하는 프로그램은?
A. 셸입니다.
Q. 리눅스의 표준 셸이며 Bourne Shell과 호환되고 csh·ksh의 장점을 결합한 셸은?
A. Bash입니다.
Q. 셸 설명 중 틀린 것은? — "bash는 빌 조이가 GNU 프로젝트를 위해 개발했고 화살표 키 편집이 불가능하다"
A. 틀린 설명입니다. bash 개발자는 브라이언 폭스이고 화살표 키 편집이 가능합니다.
Q. 현재 로그인 셸의 설정을 확인하는 명령은?
A. echo $SHELL입니다.
Q. 사용 가능한 셸 목록이 기록된 파일은?
A. /etc/shells입니다. /etc/passwd는 계정 정보, /etc/profile은 전역 환경 설정입니다.
Q. ihduser의 로그인 셸을 확인하는 명령은?
A. grep ihduser /etc/passwd입니다. 마지막(7번째) 필드가 셸입니다.
Q. 시스템 전체에 적용되는 환경 변수와 시작 프로그램을 설정하는 파일은?
A. /etc/profile입니다.
Q. 비로그인 셸의 특징으로 알맞은 것은?
A. 로그인 과정이 없어 ~/.bashrc 같은 rc 계열 파일만 주로 읽습니다.
Q. 현재 로그인한 사용자의 홈 디렉터리 경로 변수는?
A. $HOME입니다.
Q. 실행 파일을 찾는 디렉터리 경로 모음을 저장하는 변수는?
A. PATH입니다. PS1은 프롬프트, LANG은 언어입니다.
Q. 셸에서 실행한 후 저장되는 history 개수를 확인하는 환경 변수는?
A. HISTSIZE입니다.
Q. ls에 설정된 alias를 해제하는 명령은?
A. unalias ls입니다.
Q. 명령어의 표준 출력을 파일 끝에 추가하는 리다이렉션 기호는?
A. >>입니다. >는 덮어쓰기, <는 입력입니다.
💡 실무에서는?
서버 계정 보안 점검 때 저는 이번 편 내용을 그대로 씁니다.
서비스 계정 셸은 /sbin/nologin으로 막고, /etc/profile에는 TMOUT을 걸어 유휴 세션을 끊고, 관리자 PATH에서 .을 빼죠.
그리고 .bash_history는 포렌식에서 첫 번째로 보는 증적이라, 침해 사고 때 history -c로 흔적을 지운 흔적부터 찾는 경우가 많습니다. 그래서 운영 서버는 히스토리를 원격 로그 서버로 수집하는 구성이 표준이에요.
프롬프트도 습관적으로 #(root)와 $(일반 사용자)를 확인하는 게 사고 예방의 기본입니다.
운영 서버에서 root 프롬프트로 무심코 rm -rf를 치는 일만 없어도 장애의 절반은 줄어요.
핵심 정리
✅ 셸 = 명령어 해석기, 사용자 공간 최전선, 시스템 호출로 커널에 요청
✅ sh(본, 최초) csh(조이, 히스토리·별칭 최초) tcsh(그리어) ksh(콘) bash(폭스, 리눅스 표준) zsh(팔스타드)
✅ echo $SHELL / /etc/passwd 7번째 필드 / chsh -s·-l / usermod -s / /etc/shells
✅ /etc/profile(전역 환경변수) /etc/bashrc(전역 별칭·함수) ~/.bash_profile ~/.bashrc ~/.bash_logout
✅ 로그인 셸(profile 계열) vs 비로그인 셸(rc 계열), su - 는 로그인 셸
✅ 지역 변수 → export → 환경 변수, PATH=$PATH:경로 (덮어쓰기 주의)
✅ HOME USER HOSTNAME TERM TMOUT EDITOR PATH LANG PWD PS1 SHELL
✅ $$ PID / $? 종료상태 / $0 스크립트명 / $* 전체 인자 / $! 최근 백그라운드 PID
✅ history -c, !! !번호 !문자열, HISTSIZE(메모리 1000) HISTFILE(~/.bash_history) HISTFILESIZE
✅ alias / unalias, 영구 적용은 ~/.bashrc
✅ PS1: \u \h \H \w \W \t \d \! \$(# root, $ 일반)
✅ > 덮어쓰기 / >> 추가 / < 입력 / | 파이프 / & 백그라운드 / # 주석
다음 편에서는 프로세스 관리(ps, top, kill, 시그널, 데몬, 작업 제어)를 다룹니다.
기출 빈도 2위 단원이에요!
궁금한 점은 댓글로 남겨주세요!