Shell Script 정리 (1편) — 변수, 조건문, 반복문, 함수

2026. 5. 28. 15:42·블로그, 컴퓨터/Cheatsheets

shellscript cheatsheet

터미널 명령어를 익히고 나면 자연스럽게 "이 명령어들을 묶어서 자동으로 실행할 수 없을까"라는 생각이 생깁니다. 그게 Shell Script입니다.

배포 자동화, 반복 작업, 서버 세팅 같은 걸 스크립트 하나로 처리할 수 있게 됩니다. 처음엔 문법이 좀 독특해서 어색한데, 패턴이 정해져 있어서 익숙해지면 읽는 것도 쓰는 것도 어렵지 않습니다.

1편에서는 스크립트 기본 구조, 변수, 조건문, 반복문, 함수를 다룹니다.


기본 구조

#!/bin/bash

echo "Hello, World!"

첫 줄의 #!/bin/bash는 shebang이라고 부릅니다. 이 스크립트를 어떤 인터프리터로 실행할지 지정합니다. bash를 쓸 땐 #!/bin/bash, 더 호환성 높게 쓰려면 #!/usr/bin/env bash를 씁니다.

파일을 만든 뒤 실행 권한을 주고 실행합니다.

chmod +x script.sh
./script.sh

또는 권한 없이 bash script.sh로 직접 실행할 수도 있습니다.


첫 줄에 꼭 넣는 것들

#!/usr/bin/env bash
set -euo pipefail

set -euo pipefail은 스크립트를 더 안전하게 만드는 옵션 조합입니다.

  • -e : 명령어가 실패하면(종료 코드가 0이 아니면) 즉시 스크립트 종료
  • -u : 정의되지 않은 변수를 쓰면 에러
  • -o pipefail : 파이프 중간 명령어가 실패해도 에러로 처리

이게 없으면 중간에 명령어가 실패해도 스크립트가 계속 실행됩니다. 배포 스크립트 같은 데서 이게 없으면 위험합니다.


변수

선언과 사용

name="Alice"
age=30
greeting="Hello, $name"

echo $name
echo "$name"       # 따옴표 안에서도 변수 치환됨
echo "${name}!"    # 변수 이름 경계를 명확히 할 때

= 양쪽에 공백이 없어야 합니다. name = "Alice"는 에러입니다.

변수를 쓸 때는 $name이나 ${name} 둘 다 되는데, ${name} 형태가 더 안전합니다. ${name}_backup처럼 변수 이름과 다른 문자가 붙을 때 $name_backup으로 쓰면 name_backup이라는 변수로 해석되기 때문입니다.

따옴표 차이

name="World"
echo "Hello $name"    # Hello World (변수 치환 O)
echo 'Hello $name'    # Hello $name (변수 치환 X)

큰따옴표는 변수를 치환하고, 작은따옴표는 모든 것을 문자 그대로 씁니다.

환경 변수와 export

export PATH="$PATH:/usr/local/bin"    # 자식 프로세스에도 전달
export DB_HOST="localhost"

export를 붙이면 해당 스크립트에서 실행하는 하위 프로세스에도 변수가 전달됩니다.

특수 변수

$0        # 스크립트 이름
$1, $2    # 첫 번째, 두 번째 인수
$@        # 모든 인수 (각각 따로)
$*        # 모든 인수 (하나의 문자열로)
$#        # 인수 개수
$?        # 직전 명령어 종료 코드 (0 = 성공)
$$        # 현재 스크립트의 PID
$!        # 마지막 백그라운드 프로세스 PID
#!/usr/bin/env bash
echo "스크립트 이름: $0"
echo "첫 번째 인수: $1"
echo "전체 인수 수: $#"

변수 기본값

name="${1:-기본값}"          # $1이 없거나 비어있으면 기본값 사용
name="${NAME:=default}"      # 변수가 없으면 기본값으로 설정까지 함
echo "${name:-unknown}"      # 출력할 때만 기본값 적용

명령어 결과를 변수에 저장

current_date=$(date +%Y-%m-%d)
files=$(ls *.txt)
line_count=$(wc -l < file.txt)

echo "오늘 날짜: $current_date"

조건문

기본 if

if [ 조건 ]; then
  실행할 명령어
elif [ 다른조건 ]; then
  실행할 명령어
else
  실행할 명령어
fi

[ 와 ] 안쪽에 공백이 있어야 합니다. [$name]은 에러입니다.

문자열 비교

if [ "$name" = "Alice" ]; then    # 같음
if [ "$name" != "Alice" ]; then   # 다름
if [ -z "$name" ]; then           # 비어있음
if [ -n "$name" ]; then           # 비어있지 않음

문자열 비교할 때 변수를 반드시 따옴표로 감쌉니다. [ $name = "Alice" ]처럼 쓰면 name이 비어있을 때 [ = "Alice" ]가 되어 에러가 납니다.

숫자 비교

if [ "$count" -eq 0 ]; then    # equal
if [ "$count" -ne 0 ]; then    # not equal
if [ "$count" -gt 10 ]; then   # greater than
if [ "$count" -lt 10 ]; then   # less than
if [ "$count" -ge 10 ]; then   # greater or equal
if [ "$count" -le 10 ]; then   # less or equal

파일/디렉토리 확인

if [ -f "$file" ]; then        # 파일이 존재하고 일반 파일
if [ -d "$dir" ]; then         # 디렉토리가 존재
if [ -e "$path" ]; then        # 존재 (파일, 디렉토리 모두)
if [ -r "$file" ]; then        # 읽기 가능
if [ -w "$file" ]; then        # 쓰기 가능
if [ -x "$file" ]; then        # 실행 가능
if [ -s "$file" ]; then        # 비어있지 않음 (크기 > 0)

AND / OR

if [ "$a" -gt 0 ] && [ "$b" -gt 0 ]; then   # 둘 다 참
if [ "$a" -eq 0 ] || [ "$b" -eq 0 ]; then   # 하나라도 참

[[ ]] (이중 대괄호)를 쓰면 &&, ||를 안에서 쓸 수 있고, 따옴표 없이도 더 안전하게 동작합니다. bash 전용이지만 더 편합니다.

if [[ "$name" == "Alice" && "$age" -gt 20 ]]; then
if [[ "$name" =~ ^A ]]; then    # 정규식 매칭 (=~ 연산자)

반복문

for — 목록 순회

for item in apple banana cherry; do
  echo "$item"
done

# 배열 순회
fruits=("apple" "banana" "cherry")
for fruit in "${fruits[@]}"; do
  echo "$fruit"
done

# 파일 목록 순회
for file in *.txt; do
  echo "처리 중: $file"
done

# C 스타일 for
for ((i=0; i<5; i++)); do
  echo "$i"
done

while

count=0
while [ "$count" -lt 5 ]; do
  echo "$count"
  ((count++))
done

# 파일 한 줄씩 읽기
while IFS= read -r line; do
  echo "$line"
done < file.txt

파일을 한 줄씩 처리할 때 while read 패턴을 자주 씁니다. IFS=는 줄 앞뒤 공백을 보존하기 위해, -r은 백슬래시를 이스케이프로 처리하지 않기 위해 붙입니다.

until

until [ "$count" -ge 5 ]; do
  echo "$count"
  ((count++))
done

while의 반대입니다. 조건이 참이 될 때까지 반복합니다.

break / continue

for i in 1 2 3 4 5; do
  if [ "$i" -eq 3 ]; then
    continue    # 이번 회차 건너뜀
  fi
  if [ "$i" -eq 5 ]; then
    break       # 반복문 종료
  fi
  echo "$i"
done

함수

function greet() {
  echo "Hello, $1!"
}

# 또는 function 키워드 없이
greet() {
  echo "Hello, $1!"
}

greet "Alice"    # 호출

함수 안의 $1, $2는 함수 인수입니다. 스크립트 전체의 $1과는 다릅니다.

반환값

bash 함수는 숫자(0~255)만 return으로 반환할 수 있습니다. 0은 성공, 그 외는 실패를 의미합니다. 문자열은 echo로 출력하고 명령어 치환으로 받습니다.

get_date() {
  echo "$(date +%Y-%m-%d)"
}

today=$(get_date)
echo "오늘: $today"

지역 변수

함수 안에서 local을 붙이면 함수 밖에 영향을 주지 않습니다.

my_func() {
  local temp="함수 안에서만"
  echo "$temp"
}

my_func
echo "${temp:-비어있음}"    # 비어있음

배열

arr=("apple" "banana" "cherry")

echo "${arr[0]}"          # 첫 번째 요소
echo "${arr[@]}"          # 전체 요소
echo "${#arr[@]}"         # 배열 길이
arr+=("date")             # 요소 추가
unset arr[1]              # 특정 요소 삭제

# 인덱스 목록
echo "${!arr[@]}"

산술 연산

a=10
b=3

echo $((a + b))     # 13
echo $((a - b))     # 7
echo $((a * b))     # 30
echo $((a / b))     # 3 (정수 나눗셈)
echo $((a % b))     # 1 (나머지)
echo $((a ** b))    # 1000 (거듭제곱)

((a++))             # 증가
((a += 5))          # 더하기 대입

소수점 연산이 필요하면 bc를 씁니다.

echo "scale=2; 10 / 3" | bc    # 3.33

정리 표

분류 문법 용도
변수 name="value" 변수 선언
변수 "${name:-default}" 기본값 지정
변수 result=$(command) 명령어 결과 저장
특수 변수 $1 $@ $# $? 인수 / 전체 / 개수 / 종료코드
조건 [ -f ] [ -d ] [ -z ] 파일 / 디렉토리 / 빈 문자열
조건 -eq -ne -gt -lt 숫자 비교
조건 [[ =~ ]] 정규식 매칭
반복 for item in list 목록 순회
반복 while IFS= read -r line 파일 한 줄씩
함수 func() { ... } 함수 선언
함수 local var 지역 변수
산술 $((a + b)) 정수 연산

2편에서는 입력 처리, 에러 핸들링, 문자열 처리, 그리고 자주 쓰는 실용 패턴들을 정리합니다.

반응형
저작자표시 비영리 변경금지 (새창열림)

'블로그, 컴퓨터 > Cheatsheets' 카테고리의 다른 글

tmux 정리 (1편) — 세션, 윈도우, 패널  (0) 2026.05.29
Shell Script 정리 (2편) — 에러 처리, 문자열, 실용 패턴  (0) 2026.05.28
Docker 명령어 정리 (2편) — Dockerfile과 Docker Compose  (0) 2026.05.27
Docker 명령어 정리 (1편) — 개념, 이미지, 컨테이너  (0) 2026.05.27
Git 명령어 정리 (2편) — 브랜치, 원격, 되돌리기, stash  (0) 2026.05.26
'블로그, 컴퓨터/Cheatsheets' 카테고리의 다른 글
  • tmux 정리 (1편) — 세션, 윈도우, 패널
  • Shell Script 정리 (2편) — 에러 처리, 문자열, 실용 패턴
  • Docker 명령어 정리 (2편) — Dockerfile과 Docker Compose
  • Docker 명령어 정리 (1편) — 개념, 이미지, 컨테이너
생각사람
생각사람
지극히 사적인 연구실
  • 생각사람
    생각사람의 별장
    생각사람
  • 전체
    오늘
    어제
    • 분류 전체보기 (207)
      • 금융 (57)
        • 주식 공부 (11)
        • 파생상품 입문 (17)
        • 파생상품 기초 (15)
        • 파생상품 실전 (14)
      • 블로그, 컴퓨터 (83)
        • 프로그래밍 (16)
        • DevOps (8)
        • AI, RL, ML, ... (5)
        • 애드센스, SEO (23)
        • 임베디드 (3)
        • 컴퓨터 관련 (7)
        • Cheatsheets (21)
      • 다른 공부들 (67)
        • 읽고 쓰기 (18)
        • 수학 (15)
        • 물리 (9)
        • 사진 공부 (25)
  • 인기 글

  • 최근 글

  • 최근 댓글

  • 태그

    파생상품
    cmake
    깃허브
    선형대수학
    옵션 투자
    GIT
    독후감
    슈뢰딩거 방정식
    c
    코딩
    프로그래밍
    선물 옵션
    오펜하이머
    CheatSheet
    스트랭글
    행렬
    공업수학
    소니 a6000
    github
    Kreyszig
    웹크롤러
    스트래들
    옵션
    양자역학
    구글 애드센스
    AI
    version control
    벡터
    깃
    c++
  • hELLO· Designed By정상우.v4.10.6
생각사람
Shell Script 정리 (1편) — 변수, 조건문, 반복문, 함수
상단으로

티스토리툴바