CertNote/ 출퇴근 학습 노트
로드맵
KOEN
리눅스마스터 2급 · 2급리눅스마스터 2급
리눅스마스터 1급 · 1급리눅스마스터 1급
  • Week 1
    • 1.운영체제와 리눅스: 커널이 하는 일
    • 2.자유 소프트웨어와 배포판: 라이선스가 만든 생태계
    • 3.설치와 부팅: 전원을 켜는 순간부터
    • 4.파일시스템 구조와 파일의 종류: 모든 것은 파일이다
    • 5.Week 1 종합 복습: 개념을 꿰뚫는 시간
  • Week 2
  • Week 3
    • 1.셸의 정체: 명령을 해석하는 프로그램과 변수의 세계
    • 2.흐름을 잇고 비트는 기술: 리다이렉션, 파이프, 메타문자
    • 3.셸을 길들이다: 별칭, 히스토리, 그리고 작업 제어
    • 4.셸 스크립트: 명령을 코드로 엮는 첫걸음
    • 5.Week 3 종합 복습: 셸과 스크립트의 큰 그림
  • Week 4
  • Week 5
  • Week 6
  • Week 7
  • Week 8
  • Week 9
  • Week 10
  • Week 11
  • Week 12
  • Week 13
  • Week 14
합격 후기

© CertNote · 주간랩스

  • 소개
  • 수정 기록
  • 문의
  • 이용약관
  • 개인정보처리방침
← 리눅스마스터 1급/Week 3/Day 2

기준: 리눅스마스터 1급 출제 기준·오류 제보

리눅스마스터 1급· AssociateWeek 3 · Day 2읽기 약 6분
핵심 정리
  • 모든 프로세스는 FD 세 개를 갖는다 — 0 stdin · 1 stdout · 2 stderr. 리다이렉션은 이 연결 대상을 바꾸는 일이다.
  • >는 덮어쓰기(실행 전에 파일을 비운다), >>는 이어쓰기. 2>는 에러만, &>는 둘 다.
  • 2>&1은 순서가 전부다. > out 2>&1이 맞고 2>&1 > out은 stderr가 화면에 남는다.
  • 파이프는 stdout만 넘긴다. stderr까지 넘기려면 2>&1 | 또는 |&.
  • 와일드카드는 셸이 먼저 파일명으로 확장한다. 정규식의 *와 의미가 다르다. 따옴표는 작은(전부 보호)·큰(변수만 확장)·역(명령 실행).

Day 2 - 흐름을 잇고 비트는 기술: 리다이렉션, 파이프, 메타문자

파일 디스크립터: 0, 1, 2가 모든 것의 기준

"한 가지 일을 잘하는 프로그램을 만들고, 프로그램들이 협력하게 하라"는 유닉스 철학을 현실로 만든 것이 파이프와 리다이렉션이다. 그 기반이 파일 디스크립터다.

  • 리눅스에서 모든 프로세스는 시작할 때 세 개의 표준 입출력 통로를 부여받는다.
FD 번호이름약어기본 연결 대상
0표준 입력stdin키보드
1표준 출력stdout화면(터미널)
2표준 에러stderr화면(터미널)
  • 핵심은 stdout(1)과 stderr(2)가 둘 다 기본적으로 화면을 향하지만 별개의 통로라는 점이다.
  • 정상 결과는 1번으로, 에러 메시지는 2번으로 나간다. 화면에서는 섞여 보이지만 리다이렉션할 때는 따로 다룰 수 있다.

리다이렉션이란 이 FD가 가리키는 "연결 대상"을 키보드·화면이 아닌 파일이나 다른 FD로 바꾸는 것이다. 그래서 >는 "1번(stdout)을 파일로 돌려라"의 줄임이고, 2>는 "2번(stderr)을 파일로 돌려라"라는 뜻이다.

출력 리다이렉션: > 와 >>

ls -l > filelist.txt       # stdout을 파일로 (덮어쓰기)
ls -l >> filelist.txt      # stdout을 파일에 (이어쓰기)
  • > : 파일을 새로 만들거나 덮어쓴다(overwrite). 기존 내용은 사라진다.
  • >> : 파일 끝에 이어 붙인다(append). 기존 내용은 보존된다.
  • >는 사실 1>의 줄임이다. 즉 ls > out.txt와 ls 1> out.txt는 완전히 같다.

⚠️ 함정: >는 명령 실행 전에 파일을 먼저 비운다(truncate). 그래서 sort file.txt > file.txt처럼 입력과 출력이 같은 파일이면 sort가 읽기도 전에 파일이 비워져 내용이 통째로 날아간다. 같은 파일에 결과를 쓰려면 임시 파일을 거치거나 sort -o file.txt file.txt처럼 도구의 자체 옵션을 써야 한다.

에러 리다이렉션: 2> 와 stdout/stderr 분리

  • 에러 메시지(stderr, FD 2)는 2>로 따로 보낼 수 있다.
  • /dev/null은 무엇을 써도 사라지는 특수 장치로, "출력을 버린다"는 의미로 쓴다.
find / -name "*.conf" 2> errors.txt    # 에러(권한 거부 등)만 파일로
find / -name "*.conf" 2> /dev/null     # 에러를 버림 (블랙홀로)

정상 출력과 에러를 각각 다른 파일로 분리할 수도 있다.

make 1> build.log 2> error.log
# stdout → build.log, stderr → error.log

stdout과 stderr를 한 파일로 합치기

둘을 같은 파일로 모으려면 FD 복제 표기 2>&1을 쓴다. "2번을 1번이 가리키는 곳과 같게 만들어라"는 뜻이다.

command > output.txt 2>&1     # stdout과 stderr 모두 output.txt로
command &> output.txt         # 위와 동일 (bash 단축 표기)
command >> output.txt 2>&1    # 이어쓰기로 둘 다

⚠️ 함정: 2>&1의 위치(순서)가 결정적이다. command 2>&1 > out.txt는 의도와 다르게 동작한다. 셸은 왼쪽부터 처리하므로, 먼저 2>&1이 "2번을 현재 1번(화면)과 같게" 만들고, 그 뒤에 > out.txt가 1번만 파일로 바꾼다. 결과적으로 stderr는 화면에 남고 stdout만 파일로 간다. 반드시 > out.txt 2>&1 순서로 써서 1번을 먼저 파일로 돌린 뒤 2번을 1번에 합쳐야 한다.

입력 리다이렉션: < 와 히어 도큐먼트

<는 키보드(stdin) 대신 파일에서 입력을 받게 한다.

sort < names.txt          # names.txt의 내용을 sort의 입력으로
wc -l < access.log        # 파일을 입력으로 줄 수 세기
mail user@host < body.txt # 파일 내용을 메일 본문으로

여러 줄을 즉석에서 입력으로 넘기는 히어 도큐먼트(here document, <<)도 있다.

cat << END
첫 번째 줄
두 번째 줄
END
# END를 만날 때까지의 텍스트를 cat의 입력으로 전달

<<(히어 도큐먼트)와 비슷한 <<<(히어 스트링, here string)도 있다. <<<는 한 줄 문자열을 그대로 stdin으로 넘긴다. 예를 들어 grep "root" <<< "$line"은 변수 $line의 내용을 grep의 입력으로 준다. 임시 파일이나 echo | grep 파이프 없이도 문자열을 명령에 먹일 수 있어 스크립트에서 유용하다.

기호의미FD
>출력 덮어쓰기1
>>출력 이어쓰기1
<입력 받기0
2>에러 덮어쓰기2
2>>에러 이어쓰기2
&>출력+에러 덮어쓰기1,2
2>&1에러를 출력 쪽으로 합침2→1
<<히어 도큐먼트0
<<<히어 스트링0

파이프: 한 명령의 출력을 다음 명령의 입력으로

  • 파이프(|)는 앞 명령의 stdout을 뒤 명령의 stdin으로 직접 연결한다.
  • 리다이렉션이 "FD ↔ 파일"이라면, 파이프는 "FD ↔ FD"(프로세스끼리)다.
  • 파이프로 연결된 명령들은 동시에(병렬로) 실행되며, 데이터는 커널이 관리하는 파이프 버퍼를 통해 흐른다.
ls -l | grep ".txt"                  # 목록에서 .txt만 추리기
cat access.log | grep "404" | wc -l  # 404 응답 줄 수 세기
ps aux | grep nginx                  # 실행 중 nginx 프로세스 찾기
du -h | sort -rh | head -5           # 용량 큰 항목 상위 5개

파이프는 stdout만 다음으로 넘긴다. stderr(2번)는 파이프를 타지 않고 화면에 남는다. stderr까지 파이프로 넘기려면 command 2>&1 | next 또는 bash의 command |& next 표기를 쓴다.

필터: 파이프 사이에 끼어 데이터를 가공하는 명령

필터(filter)는 stdin으로 받아 가공한 뒤 stdout으로 내보내는 명령으로, 파이프라인의 중간 단계에 쓰인다.

필터역할
grep패턴에 맞는 줄만 거르기
sort정렬 (-r 역순, -n 숫자, -k 필드)
uniq인접 중복 줄 제거 (-c 개수 세기)
wc줄·단어·바이트 수 세기 (-l, -w, -c)
head / tail앞/뒤 N줄 (tail -f 실시간)
cut필드·문자 단위 잘라내기 (-d, -f)
tr문자 치환·삭제
sed스트림 편집(치환·삭제)
awk필드 기반 텍스트 처리
tee화면 출력과 파일 저장 동시에

tee는 특히 유용하다 — 파이프 중간에서 흐름을 화면과 파일로 동시에 분기한다.

ls -l | tee filelist.txt | grep ".sh"
# 전체 목록을 filelist.txt에 저장하면서 동시에 .sh만 화면에 표시
make 2>&1 | tee build.log    # 빌드 로그를 보면서 파일로도 기록

tee라는 이름은 배관에서 물길을 둘로 나누는 T자 관(tee fitting)에서 왔다. 하나의 입력을 두 갈래(파일·화면)로 흘려보내는 모양이 알파벳 T와 닮았다. 유닉스 명령 이름에는 이처럼 일상 사물에서 따온 작명이 많다.

메타문자와 와일드카드: 셸이 먼저 가로채는 특수 기호

  • 명령을 실행하기 전에 셸은 입력 줄에서 특수한 의미를 가진 문자(메타문자, metacharacter)를 먼저 처리한다.
  • 그중 파일 이름을 매칭하는 데 쓰는 것을 와일드카드(wildcard) 또는 글로빙(globbing)이라 한다.
와일드카드의미예시
*0개 이상의 임의 문자*.txt → 모든 .txt
?정확히 1개의 임의 문자file?.log → file1.log, fileA.log
[ ]괄호 안 문자 중 하나file[123].txt
[a-z]범위 안의 한 문자[a-c]* → a,b,c로 시작
[!abc]괄호 안 문자를 제외한 하나[!0-9]* → 숫자로 시작 안 함
{ }중괄호 확장(brace)file{1,2,3}.txt
ls *.txt              # 확장자가 .txt인 모든 파일
rm temp?.log          # temp 뒤에 한 글자 + .log
ls [a-c]*             # a, b, c로 시작하는 모든 파일
cp file{1,2,3}.txt /backup/   # file1.txt file2.txt file3.txt 복사
ls *[!0-9]            # 마지막 글자가 숫자가 아닌 파일

와일드카드 확장(globbing)을 수행하는 주체는 명령이 아니라 셸이다. ls *.txt를 입력하면 셸이 먼저 *.txt를 실제 파일 이름들(a.txt b.txt c.txt)로 바꾼 뒤, 그 결과를 ls에게 인자로 넘긴다. 그래서 매칭되는 파일이 하나도 없으면 bash 기본 동작에서는 *.txt가 글자 그대로 ls에게 전달된다. 이 "셸이 먼저 확장한다"는 점은 정규표현식과 와일드카드의 결정적 차이로 이어진다.

와일드카드(글로빙)와 정규표현식(regex)을 혼동하면 안 된다. 둘 다 *를 쓰지만 의미가 다르다. 글로빙에서 *는 "임의의 0개 이상 문자"지만, 정규표현식에서 *는 "바로 앞 문자의 0회 이상 반복"이다. 예를 들어 글로빙 a*는 a로 시작하는 모든 것이지만, regex a*는 a가 0번 이상(즉 빈 문자열 포함)을 뜻한다. grep의 패턴은 정규표현식, 파일 이름 매칭은 글로빙이다.

따옴표: 셸의 확장을 제어하는 세 가지 인용

메타문자를 글자 그대로 쓰고 싶거나 변수 확장을 제어하려면 따옴표를 쓴다. 세 종류의 동작이 모두 다르다.

따옴표이름변수($) 확장명령 치환(`)와일드카드
' '작은따옴표(strong)❌❌❌
" "큰따옴표(weak)✅✅❌
` `역따옴표(backtick)—명령 실행—
NAME="linux"
 
echo '$NAME'      # $NAME      (작은따옴표: 전혀 확장 안 함)
echo "$NAME"      # linux      (큰따옴표: 변수만 확장)
echo `date`       # 현재 날짜  (역따옴표: 명령 실행 결과로 치환)
  • 작은따옴표('): 안의 모든 것을 문자 그대로 취급한다. $, *, 공백 모두 글자다.
  • 큰따옴표("): 변수($VAR)와 명령 치환(`cmd`)은 확장하되, 와일드카드는 막는다. 공백을 포함한 값을 안전하게 다룰 때 필수다.
  • 역따옴표(`): 안의 명령을 실행해 그 출력으로 치환한다(명령 치환). 현대 bash에서는 $(...) 표기를 더 권장한다.
# 명령 치환 — 두 표기는 동일, $() 가 중첩에 안전
echo "오늘은 `date +%Y-%m-%d` 입니다"
echo "오늘은 $(date +%Y-%m-%d) 입니다"
 
# 변수 값에 공백이 있을 때 큰따옴표의 중요성
FILE="my report.txt"
rm "$FILE"        # 올바름: 'my report.txt' 한 파일 삭제
rm $FILE          # 위험: 'my'와 'report.txt' 두 인자로 분리됨

큰따옴표로 변수를 감싸야 하는 이유는 단어 분리(word splitting) 때문이다. 따옴표 없이 변수를 쓰면 셸이 값 안의 공백을 기준으로 여러 인자로 쪼갠다. 그래서 스크립트에서는 거의 항상 "$VAR"처럼 큰따옴표로 감싸는 것이 안전한 관용구다.

역따옴표 명령 치환의 가장 큰 약점은 중첩이다. `cmd1 `cmd2` `처럼 역따옴표를 겹치면 어디서 끝나는지 셸이 헷갈린다. 1990년대 POSIX가 $(...) 문법을 도입한 가장 큰 이유가 이 중첩 문제 해결이었다. $(cmd1 $(cmd2))처럼 괄호로 명확히 중첩되므로 오늘날 스크립트에서는 $()가 표준이다.

이스케이프: 백슬래시로 한 글자만 보호하기

따옴표 대신 백슬래시(\)로 바로 뒤의 한 글자만 특수 의미를 제거할 수도 있다.

echo \$NAME       # $NAME (달러 기호를 글자로)
echo file\ name   # 'file name' (공백을 글자로)
touch a\*b        # 'a*b'라는 이름의 파일 생성

내일은 alias·history·작업 제어를 다룬다.

📖 용어

  • 파일 디스크립터(FD) : 프로세스가 입출력 통로에 붙이는 번호표. 0=입력, 1=출력, 2=에러.
  • stdout / stderr : 정상 결과가 나가는 1번 통로와 에러가 나가는 2번 통로. 화면에선 섞여 보여도 별개다.
  • 리다이렉션 : FD가 향하는 곳을 화면·키보드에서 파일이나 다른 FD로 바꾸는 일.
  • > vs >> : 덮어쓰기와 이어쓰기. >는 명령이 실행되기 전에 파일을 비운다.
  • 2>&1 : "2번을 1번이 가는 곳과 같게 하라". 반드시 > 파일 뒤에 써야 의도대로 동작한다.
  • /dev/null : 무엇을 써도 사라지는 특수 장치. 출력을 버릴 때 쓴다.
  • 히어 도큐먼트(<<) : 종료 표시를 만날 때까지의 여러 줄을 그대로 명령의 입력으로 넘기는 문법.
  • 파이프(|) : 앞 명령의 stdout을 뒤 명령의 stdin에 직결. stderr는 타지 않는다.
  • 필터(filter) : stdin으로 받아 가공해 stdout으로 내보내는 명령. 파이프라인의 중간 부품.
  • tee : 흐름을 파일과 화면 두 갈래로 나누는 명령. 이름은 배관의 T자 관에서 왔다.
  • 글로빙(globbing) : 셸이 *·?·[]를 실제 파일 이름으로 미리 바꾸는 확장. 정규식과 다르다.
  • 단어 분리(word splitting) : 따옴표 없는 변수 값이 공백 기준으로 여러 인자로 쪼개지는 현상. "$VAR"로 막는다.
  • 명령 치환 : `cmd` 또는 $(cmd)로 명령의 출력을 그 자리에 끼워 넣는 것. 중첩에는 $()가 안전하다.

📝 연습 문제

선택지를 클릭하면 정답·해설이 펼쳐집니다.

문제 1

표준 에러(stderr)에 해당하는 파일 디스크립터 번호는?

문제 2

command > output.txt 2>&1 의 동작으로 옳은 것은?

문제 3

명령의 출력을 화면에 보여주는 동시에 파일에도 저장하는 필터는?

문제 4

와일드카드 ?의 의미로 옳은 것은?

문제 5

다음 중 변수 $NAME을 확장하지 않고 글자 그대로 출력하는 것은?

문제 6

sort file.txt > file.txt 를 실행했을 때 발생하는 결과는?

문제 7

명령 치환(command substitution)을 수행하는 표기로 올바르게 짝지어진 것은?

이전셸의 정체: 명령을 해석하는 프로그램과 변수의 세계Week 3 · Day 1다음 셸을 길들이다: 별칭, 히스토리, 그리고 작업 제어Week 3 · Day 3

참고 공식 자료

  • 리눅스마스터 1급 공식 출제 기준(새 탭에서 열림)

이 페이지

  • 파일 디스크립터: 0, 1, 2가 모든 것의 기준
  • 출력 리다이렉션: > 와 >>
  • 에러 리다이렉션: 2> 와 stdout/stderr 분리
  • stdout과 stderr를 한 파일로 합치기
  • 입력 리다이렉션: < 와 히어 도큐먼트
  • 파이프: 한 명령의 출력을 다음 명령의 입력으로
  • 필터: 파이프 사이에 끼어 데이터를 가공하는 명령
  • 메타문자와 와일드카드: 셸이 먼저 가로채는 특수 기호
  • 따옴표: 셸의 확장을 제어하는 세 가지 인용
  • 이스케이프: 백슬래시로 한 글자만 보호하기
  • 용어
  • 연습 문제