단순 명령 · 파이프라인 · 리스트 — 명령을 잇는 기호들

이 글은 GNU Bash 매뉴얼 3.2 Shell Commands 가운데 예약어·단순 명령·파이프라인·리스트(3.2.1–3.2.4)를, 처음 배우는 분도 따라올 수 있게 쉬운 말로 풀어 정리합니다. 한 줄짜리 명령을 넘어, |·&&·||·;·&​여러 명령을 어떻게 이어 붙이는지 가 핵심입니다.

이 글을 읽고 나면

  • 단순 명령이 “명령 이름 + 인자들”로 구성된다는 점을 설명할 수 있습니다.

  • 파이프(|)가 앞 명령의 출력을 뒤 명령의 입력으로 넘긴다는 것을 이해합니다.

  • && / || / ; / &의 차이를 구분하고, 상황에 맞게 고를 수 있습니다.

  • 파이프라인의 성공/실패가 기본으로 “맨 오른쪽”만 본다는 함정을 압니다.

큰 그림: 명령을 쌓는 세 층

셸에서 자주 쓰는 명령 구조를 층으로 나누면 이해하기 쉽습니다.

Text

① 단순 명령 echo hello world └─ 명령 하나 + 인자들 ② 파이프라인 cmd1 | cmd2 | cmd3 └─ 앞 출력 → 뒤 입력으로 연결 ③ 리스트 A && B || C ; D & └─ 성공/실패·순서·백그라운드로 여러 파이프를 이어 붙임

이전 글에서 셸이 한 줄을 “나누고 → 펼치고 → 실행”한다고 했습니다. 이번 글은 그렇게 실행되는 ​명령들을 어떻게 이어 붙이는지 에 초점을 둡니다.

예약어 — 특별한 뜻을 가진 단어

if, for, while, then, do, !, [[ 같은 단어는 셸이 ​특별한 뜻 으로 알아듣는 예약어입니다. 보통 ​따옴표 없이, 그리고 ​명령의 첫 단어 로 나올 때 예약어로 취급됩니다.

예약어 예

나중에 다루는 용도

if then else fi

조건 분기

for while until do done

반복

!

“성공/실패를 뒤집기” (파이프 앞에 자주 씀)

[[ ]]

Bash 조건식

{ }

명령 묶기

지금은 “이런 단어들이 있다” 정도만 기억해도 충분합니다. 따옴표로 감싸면("if") 일반 글자가 되어, 예약어로 동작하지 않습니다.

단순 명령 — 가장 자주 쓰는 형태

​단순 명령 은 공백으로 나뉜 단어들의 나열입니다.

Bash

printf '%s\n' apple banana cherry
  • ​첫 단어 → 실행할 명령 (printf)

  • ​나머지 단어 → 그 명령에 넘기는 인자 ('%s\n', apple, …)

명령이 끝나면 ​종료 코드 가 남습니다.

종료 코드

의미 (관례)

0

성공

0이 아님

실패 (또는 “찾지 못함” 등 상황별 코드)

이 성공/실패 값이 바로 아래에서 배울 && / ||의 판단 기준이 됩니다.

파이프라인 — 앞의 결과를 뒤로 흘려보내기

​파이프라인 은 명령을 |로 이은 것입니다.

Bash

printf '%s\n' apple banana cherry | grep a | wc -l

동작 방식은 간단합니다.

Text

printf 가 만든 출력 ──│──▶ grep 의 입력 grep 가 만든 출력 ──│──▶ wc 의 입력

앞에서 나온 글자가, 파일로 저장하지 않고도 ​바로 다음 명령의 입력 이 됩니다. 데이터를 흘려보내는 호스(pipe)를 상상하면 됩니다.

알아 둘 세부 사항입니다.

항목

쉬운 설명

기본 종료 코드

​맨 오른쪽 명령 의 성공/실패만 전체가 됩니다

pipefail

켜 두면, 중간 단계가 실패해도 전체 실패로 봅니다

! 를 앞에

성공/실패를 뒤집습니다 (! true → 실패처럼)

|&

표준 출력뿐 아니라 에러 출력도 파이프로 (Bash 4+; 2>&1 | 와 같음)

리스트 — 명령을 “언제, 어떤 순서로” 실행할지

​리스트 는 파이프라인(또는 단순 명령)을 ; · & · && · ||로 이은 것입니다. 실무에서 가장 많이 쓰는 네 가지를 비교합니다.

; — 순서대로, 성공/실패와 무관

Bash

echo first; echo second

앞이 끝나야 뒤가 시작합니다. 앞이 실패해도 ​뒤는 그대로 실행됩니다.

&& — 앞이 성공할 때만 뒤 실행

Bash

mkdir -p out && cp file.txt out/

“만들기에 성공했을 때만 복사한다”처럼 ​전제 조건 을 걸 때 씁니다. 앞이 실패하면 뒤는 건너뜁니다.

|| — 앞이 실패할 때만 뒤 실행

Bash

grep -q pattern file.txt || echo "not found"

“찾기에 실패했을 때만 안내 메시지를 낸다”처럼 ​대체 동작·에러 처리 에 씁니다.

& — 백그라운드(비동기)

Bash

long_job &

셸이 끝날 때까지 ​기다리지 않고 다음으로 넘어갑니다. 스크립트에서는 종료 시점을 wait로 맞추는 일이 많아, 자세한 내용은 이후 Job Control 글에서 다룹니다. 지금은 “앞에 &를 붙이면 기다리지 않는다” 정도만 기억하세요.

한눈에 비교

기호

앞이 성공하면

앞이 실패하면

기다림

;

뒤 실행

뒤 실행

앞이 끝날 때까지

&&

뒤 실행

뒤 건너뜀

앞이 끝날 때까지

||

뒤 건너뜀

뒤 실행

앞이 끝날 때까지

&

(백그라운드)

(백그라운드)

​기다리지 않음

우선순위는 대략 && / ||가 같고, 그다음 ; / &입니다. 복잡한 한 줄보다, 읽기 쉽게 줄을 나누는 편이 유지보수에 유리합니다.

실행 예제

아래 스크립트는 단순 명령, 파이프, && / || / ;, 그리고 파이프 종료 코드의 차이를 한 화면에서 보여 줍니다.

Bash

#!/usr/bin/env bash # 단순 명령 · 파이프 · && / || / ; 를 한 화면에서 비교합니다. set -eu echo "=== 1) 단순 명령: 명령 + 인자 ===" printf '%s\n' apple banana cherry # (1) 첫 단어=명령, 나머지=인자 echo echo "=== 2) 파이프라인: 앞 출력 → 뒤 입력 ===" printf '%s\n' apple banana cherry | grep a | wc -l # (2) a 가 들어간 줄 개수 echo echo "=== 3) && : 앞이 성공할 때만 뒤 실행 ===" true && echo "left ok → right runs" # (3) true 는 항상 성공(종료 코드 0) echo echo "=== 4) || : 앞이 실패할 때만 뒤 실행 ===" false || echo "left failed → right runs" # (4) false 는 항상 실패(비0) echo echo "=== 5) ; : 성공/실패와 관계없이 순서대로 ===" echo first; echo second # (5) 앞이 끝나야 뒤가 시작 echo echo "=== 6) 파이프 종료 코드: 기본은 마지막만 ===" set +e # (6) 아래 데모에서 실패해도 스크립트 중단 방지 set +o pipefail # (7) 기본: 파이프 결과는 맨 오른쪽 기준 false | true echo "without pipefail: exit=$?" # (8) 대개 0 (true 의 결과) set -o pipefail # (9) 중간에 실패한 단계도 실패로 취급 false | true echo "with pipefail: exit=$?" # (10) 대개 1 (false 의 결과) echo echo "ok — 명령을 잇는 기호마다 의미가 다릅니다."

​주요 라인별 설명
1: 단순 명령 — printf가 명령이고, 뒤는 모두 인자입니다.
2: |로 세 단계를 이어, 앞 출력이 뒤 입력이 됩니다.
3: && — 왼쪽이 성공(0)일 때만 오른쪽이 실행됩니다.
4: || — 왼쪽이 실패(비0)일 때만 오른쪽이 실행됩니다.
5: ; — 성공/실패와 무관하게 앞→뒤 순서로 실행됩니다.
6–8: pipefail이 꺼져 있으면 false | true의 종료 코드는 오른쪽(true) 기준이라 0에 가깝습니다.
9–10: pipefail을 켜면 중간 실패가 전체에 반영되어 비0이 됩니다.

실행하면 대략 이런 결과가 나옵니다.

Text

=== 1) 단순 명령: 명령 + 인자 === apple banana cherry === 2) 파이프라인: 앞 출력 → 뒤 입력 === 2 === 3) && : 앞이 성공할 때만 뒤 실행 === left ok → right runs === 4) || : 앞이 실패할 때만 뒤 실행 === left failed → right runs === 5) ; : 성공/실패와 관계없이 순서대로 === first second === 6) 파이프 종료 코드: 기본은 마지막만 === without pipefail: exit=0 with pipefail: exit=1

(wc -l 숫자의 앞쪽 공백은 환경에 따라 조금 다를 수 있습니다. 값은 “2”입니다.)

헷갈리기 쉬운 부분

  1. &&;를 혼동;는 앞이 실패해도 뒤를 돌립니다. “성공했을 때만” 이려면 &&입니다.

  2. ||를 “그리고”처럼 읽기||는 “또는/실패 시”에 가깝습니다. 둘 다 성공해야 하면 &&를 쓰세요.

  3. ​파이프 중간 실패를 놓침 — 기본은 맨 오른쪽만 봅니다. 중요한 파이프에는 set -o pipefail을 고려하세요.

  4. |&가 안 됨 — 일부 환경(예: 오래된 Bash 3.2)에는 없습니다. 같은 뜻으로 2>&1 |를 쓰면 됩니다.

  5. ​화면에 출력이 없어도 실패일 수 있음 — 분기할 때는 출력보다 ​종료 코드 를 기준으로 생각하세요.

한 줄 요약

**​단순 명령은 ‘이름 + 인자’이고, |는 출력을 다음 입력으로 흘려보내며, &&/||/;/&는 언제·어떤 순서로 이을지를 정합니다. 파이프의 성공/실패는 기본이 맨 오른쪽이니, 필요할 때 pipefail을 기억하세요.

On this page