[Linux] Bash 쉘-프로그래밍

Bash 스크립트 완전 가이드

실무에서 자주 쓰는 명령어와 스크립트 패턴 총정리

read · 산술연산 · 조건문루프 · 함수 · trapawk · sed · grepfind · systemctl · 네트워크

📋 목차

  1. read 명령어
  2. 산술 연산
  3. 위치 파라미터
  4. 조건문 · test 명령
  5. 루프 명령 (for/while/until)
  6. 함수
  7. 트랩 (trap) 시그널
  8. grep 고급 옵션 ✨
  9. awk / sed 명령어 ✨
  10. find · 유용한 유틸리티

01

read 명령어

빌트인 명령으로 터미널 또는 파일로부터 입력 문자열을 읽을 때 사용합니다.

옵션의미
read answer표준 입력으로 한 라인을 읽고 answer 변수에 할당
read first last공백 기준으로 첫 단어 → first, 나머지 → last
read한 라인을 읽고 빌트인 $REPLY 변수에 저장
read -a arrayname입력을 공백 기준으로 배열 arrayname에 저장
read -e대화형 쉘에서 readline 편집 활성화
read -p prompt프롬프트를 출력하고 입력 대기, $REPLY에 저장
read -r line백슬래시(\)를 이스케이프 처리 없이 그대로 읽음
read -t 초지정한 초 안에 입력 없으면 타임아웃 (종료 상태 1 반환)
read -s입력 내용을 화면에 표시하지 않음 (비밀번호 입력 등)

예제 스크립트

bash

#!/bin/bash
# question.sh

echo -e "행복하세요? : \c"
read answer
echo "$answer 라고 대답하셨네요"

read -p "사용하는 리눅스 배포판: "
echo $REPLY

read -a dist    # 배열로 읽기
echo "${dist[0]}를 첫 번째로 입력했습니다"

read -s -p "비밀번호 입력: " pw   # 입력 숨김
echo

💡 Tip:read -t 5 -p "5초 안에 입력하세요: " ans — 타임아웃을 활용하면 자동화 스크립트에서 사용자 응답을 기다릴 수 있습니다.

02

산술 연산

정수형 연산

방법예시설명
declare -ideclare -i num=10+5정수형 변수 선언
letlet "i += 5"빌트인 정수 연산
(( ))(( x = 3 * 4 ))이중 괄호 산술 (권장)
$(( ))result=$(( 10 % 3 ))산술 치환으로 값 저장

진수 표기

형식예시10진수 결과
2진수declare -i x=2#101010
8진수declare -i x=8#1311
16진수declare -i x=16#ff255

실수형 연산 (bc / awk)

bash

# bc: 소수점 2자리까지 나눗셈
n=`echo "scale=2; 20 / 3" | bc`
echo $n   # → 6.66

# awk: 실수 곱셈
m=`awk -v x=2.66 -v y=5.22 'BEGIN{printf "%.2f\n", x*y}'`
echo $m   # → 13.89

# 제곱근 구하기
echo "sqrt(2)" | bc -l   # → 1.41421356...

03

위치 파라미터 & 명령라인 아규먼트

변수의미
$0실행한 스크립트 이름
$1 … ${10}위치 파라미터 (10 이상은 중괄호 필수)
$#파라미터 개수
“$*”모든 파라미터를 하나의 문자열로 → "$1 $2 $3"
“$@”각 파라미터를 분리된 문자열로 → "$1" "$2" "$3"
$?직전 명령의 종료 상태 (0=성공, 1=실패)
$$현재 쉘의 PID
$!마지막 백그라운드 프로세스 PID

✅ $* vs $@: 큰따옴표로 감쌀 때만 차이가 납니다. "$@"는 각 파라미터의 공백을 보존하므로 파일명 처리 등에서 항상 "$@"를 사용하세요.

set 명령으로 파라미터 재설정

bash

set CentOS Fedora Ubuntu    # 위치 파라미터 재설정
echo $*                       # CentOS Fedora Ubuntu

set $(date)                  # date 출력으로 파라미터 재설정
echo "오늘은 $2 $3 $1"

set --                       # 모든 파라미터 초기화

04

조건문 & test 명령

문자열 테스트

연산자참(true)일 때
[ str1 == str2 ]문자열이 같을 때
[ str1 != str2 ]문자열이 다를 때
[ -z str ]문자열 길이가 0 (빈 문자열)
[ -n str ]문자열 길이가 0이 아님
[[ str == pat* ]]글로브 패턴 매칭
[[ str =~ regex ]]정규식 매칭 (bash 3.0+)

정수형 테스트

연산자의미(( )) 동등 표현
-eq같음 (equal)==
-ne다름 (not equal)!=
-gt초과 (greater than)>
-ge이상 (greater or equal)>=
-lt미만 (less than)<
-le이하 (less or equal)<=

파일 테스트

연산자참일 때
-e filename파일이 존재
-f filename일반 파일
-d filename디렉터리
-r filename읽기 가능
-w filename쓰기 가능
-x filename실행 가능
-s filename크기가 0보다 큼
-L filename심볼릭 링크
-z filename파일 크기가 0 (빈 파일)
file1 -nt file2file1이 더 최근에 수정됨
file1 -ot file2file1이 더 오래됨

if / elif / else 패턴

bash

#!/bin/bash
# qa.sh — 점수 판정

read -p "점수 입력 (0-100): " num

if [[ ! $num =~ ^[0-9]+$ ]]; then
    echo "숫자를 입력하세요."; exit 1
elif (( num < 70 )); then   echo "70점 미만"
elif (( num < 80 )); then   echo "70점대"
elif (( num < 90 )); then   echo "80점대"
elif (( num < 100 )); then  echo "90점대"
else                           echo "만점! 🎉"
fi

case 명령

bash

read -p "색 입력: " color
case $color in
    [Bb]l??)        echo "파란색" ;;
    [Gg]ree*)       echo "녹색"   ;;
    red|orange)     echo "빨간색/주황" ;;
    *)              echo "알 수 없음" ;;
esac

05

루프 명령 (for / while / until / select)

for 루프

bash

# 목록 순회
for name in 홍길동 장보고 이순신; do
    echo "안녕하세요, $name님"
done

# C 스타일 (bash 전용)
for (( i=1; i<=5; i++ )); do
    echo $i
done

# 범위 지정 (brace expansion)
for i in {1..10..2}; do   # 1 3 5 7 9 (step=2)
    echo $i
done

# 파일 목록 처리
for file in /var/log/*.log; do
    echo "처리 중: $file"
done

while 루프

bash

# 카운터
number=0
while (( number < 10 )); do
    printf "%d " $number
    (( number++ ))
done

# 파일을 한 줄씩 읽기
while IFS= read -r line; do
    echo "$line"
done < /etc/passwd

until 루프

bash

# 조건이 참이 될 때까지 반복 (while의 반대)
hour=0
until (( hour >= 24 )); do
    case $hour in
        [0-9]|1[01]) echo "${hour}시: 오전" ;;
        12)          echo "12시: 정오"   ;;
        *)           echo "${hour}시: 오후" ;;
    esac
    (( hour++ ))
done

루프 제어 — break / continue / shift

명령동작
break현재 루프 즉시 종료
break nn번째 바깥쪽 루프까지 종료
continue루프 최상단으로 이동 (다음 반복)
continue nn번째 바깥쪽 루프 다음 반복으로 이동
shift n파라미터 목록을 n칸 좌측으로 이동 (기본값 1)

06

함수

함수는 현재 쉘 컨텍스트에서 실행되며 자식 프로세스를 생성하지 않습니다.

개념설명
local 변수함수 내부에서만 유효, 종료 시 자동 제거
return n함수 종료 및 종료 상태 반환 (0~255)
export -f fn함수를 서브쉘로 전달 (전역화)
unset -f fn함수 정의 제거
declare -f정의된 함수 목록과 내용 출력
source ./file외부 파일의 함수를 현재 스크립트에서 사용

bash

#!/bin/bash

# 기본 함수 정의
greet() {
    local name=$1
    echo "안녕하세요, ${name}님!"
}

# 반환값 활용
square() {
    local result
    (( result = $1 * $1 ))
    echo $result          # echo로 값 출력 → 명령치환으로 받음
}

greet "홍길동"
val=$(square 5)
echo "5의 제곱: $val"    # → 25

# 외부 함수 파일 로드
source ./myfunction
os

💡 반환값 패턴:return은 0~255 정수만 반환 가능합니다. 문자열이나 큰 숫자는 echo로 출력하고 $(함수명)으로 받는 패턴을 사용하세요.

07

트랩 (trap) 시그널 처리

시그널번호발생 조건
SIGHUP1터미널 연결 끊김
SIGINT2Ctrl+C
SIGQUIT3Ctrl+\
SIGKILL9강제 종료 (trap 불가)
SIGTERM15kill 명령 기본값
SIGTSTP20Ctrl+Z (일시중지)
EXIT0스크립트 종료 시

bash

#!/bin/bash

# 종료 시 임시 파일 자동 정리 (EXIT 트랩)
TMPFILE=$(mktemp)
trap "rm -f $TMPFILE; echo '정리 완료'" EXIT

# Ctrl+C 가로채기
trap 'echo "중단하려면 \"stop\" 입력"' INT

# 시그널 무시
trap "" HUP          # HUP 시그널 무시

# 기본 동작으로 복원
trap - INT            # INT 시그널 기본값으로 복원

# 트랩 목록 확인
trap -p               # 현재 설정된 트랩 출력

✅ 실무 패턴:trap "cleanup; exit" INT TERM EXIT — 임시 파일, 락 파일 정리에 EXIT 트랩을 적극 활용하세요.

08

grep 고급 옵션 NEW

grep은 파일이나 표준 입력에서 패턴과 일치하는 줄을 검색합니다.

옵션의미예시
-i대소문자 구분 없이 검색grep -i error log.txt
-v패턴과 일치하지 않는 줄 출력grep -v "#" config
-n줄 번호 함께 출력grep -n "main" script.sh
-c매칭된 줄 수만 출력grep -c "error" app.log
-l매칭된 파일명만 출력grep -l "TODO" *.sh
-r하위 디렉터리 재귀 검색grep -r "function" /scripts
-E확장 정규식 사용 (egrep 동일)grep -E "err|warn" log
-w단어 단위로 정확히 매칭grep -w "root" /etc/passwd
-A n매칭 줄 이후 n줄 함께 출력grep -A 3 "ERROR" log
-B n매칭 줄 이전 n줄 함께 출력grep -B 2 "ERROR" log
-C n앞뒤 n줄 모두 출력grep -C 2 "ERROR" log
–color매칭 부분을 색상으로 강조grep --color "root" /etc/passwd

bash

# 실무 활용 예제

# 로그에서 ERROR 또는 WARN 검색, 줄번호 포함
grep -nE "ERROR|WARN" /var/log/syslog

# 주석·공백 제거 후 설정 파일 확인
grep -vE "^#|^$" /etc/ssh/sshd_config

# 프로세스 목록에서 특정 프로세스 확인 (grep 자신 제외)
ps aux | grep -v grep | grep nginx

# 재귀 검색 + 파일명만 출력
grep -rl "#!/bin/bash" /home/

# 여러 패턴 동시 검색
grep -e "error" -e "fail" -e "crash" app.log

09

awk / sed 명령어 NEW

awk — 필드 기반 텍스트 처리

awk는 파일을 레코드(행)와 필드(열)로 분리하여 처리하는 강력한 도구입니다.

변수/패턴의미
$0전체 라인
$1, $2, …공백 기준 n번째 필드
NF현재 행의 필드 수 (마지막 필드: $NF)
NR현재 처리 중인 줄 번호
FS필드 구분자 (기본: 공백/탭)
OFS출력 필드 구분자
BEGIN{}파일 처리 전 실행되는 블록
END{}파일 처리 후 실행되는 블록

bash

# 기본: 2번째 필드 출력
awk '{print $2}' file.txt

# 구분자 지정 (-F): /etc/passwd에서 사용자명·쉘 출력
awk -F: '{print $1, $7}' /etc/passwd

# 조건부 출력: 3번째 필드가 1000 이상인 행
awk -F: '$3 >= 1000 {print $1, $3}' /etc/passwd

# BEGIN/END: 합계 계산
awk 'BEGIN{sum=0} {sum+=$1} END{print "합계:", sum}' numbers.txt

# 줄 번호 추가
awk '{print NR"\t"$0}' file.txt

# 특정 패턴이 있는 줄만 처리
awk '/ERROR/{print NR, $0}' app.log

# printf로 정렬 출력
awk -F: '{printf "%-15s %s\n", $1, $6}' /etc/passwd

sed — 스트림 편집기

sed는 파일을 직접 수정하거나 파이프라인에서 텍스트를 변환할 때 사용합니다.

명령의미예시
s/old/new/첫 번째 매칭 치환sed 's/foo/bar/'
s/old/new/g전체 치환sed 's/foo/bar/g'
s/old/new/i대소문자 무시 치환sed 's/FOO/bar/gI'
d줄 삭제sed '/^#/d'
p줄 출력 (-n과 함께)sed -n '5p'
a\ text지정 줄 다음에 추가sed '3a\ 추가내용'
i\ text지정 줄 앞에 삽입sed '1i\ 제목'
-i파일 직접 수정 (in-place)sed -i 's/old/new/g' f
-n자동 출력 억제sed -n '1,5p' file

bash

# 특정 줄 범위 출력 (5~10번째 줄)
sed -n '5,10p' file.txt

# 주석·빈 줄 제거
sed -E '/^#|^$/d' config.conf

# 파일 직접 수정 (백업 생성: .bak)
sed -i.bak 's/192.168.1.1/10.0.0.1/g' config.txt

# 여러 명령 동시 실행 (-e)
sed -e 's/foo/bar/g' -e '/^$/d' file.txt

# 특정 줄 삭제 (3번째 줄)
sed '3d' file.txt

# 패턴 사이 줄 추출
sed -n '/START/,/END/p' file.txt

⚠️ 주의:sed -i는 원본 파일을 직접 수정합니다. 중요 파일은 반드시 sed -i.bak으로 백업을 생성하세요.

10

find & 유용한 유틸리티

find 주요 옵션

옵션의미
-name 패턴파일명으로 검색 (와일드카드 가능)
-type f/d/l타입: 일반파일/디렉터리/심볼릭링크
-mtime +n/-nn일 초과/이내 수정된 파일
-size +n/-nn블록 초과/미만 파일 (k=KB, M=MB)
-perm nnn퍼미션이 nnn인 파일
-user 유저명특정 소유자의 파일
-exec cmd {}검색된 파일에 명령 실행
-delete검색된 파일 삭제
-maxdepth n탐색 깊이 제한

bash

# 30일 이상 된 로그 파일 삭제
find /var/log -name "*.log" -mtime +30 -delete

# 퍼미션 755인 파일 검색
find . -type f -perm 755

# 빈 파일 검색 후 삭제
find . -empty -type f -delete

# 검색 결과로 명령 실행
find . -name "*.sh" -exec chmod +x {} \;

# xargs와 결합 (더 빠름)
find /tmp -name "core" -type f | xargs rm -f

유용한 텍스트 처리 유틸리티

명령설명예시
cut -f2탭 구분 n번째 필드 추출cut -f2 file.txt
cut -d: -f1구분자 지정 후 필드 추출cut -d: -f1 /etc/passwd
paste f1 f2두 파일을 열 방향으로 합치기paste sname sprice
join f1 f2공통 키 기준으로 파일 합치기join sname sprice
tr a-z A-Z소문자 → 대문자 변환echo "hello" | tr a-z A-Z
tr -d ‘\r’Windows 개행 제거tr -d '\r' < win.txt
uniq인접 중복 라인 제거sort file | uniq
uniq -c중복 횟수와 함께 출력sort file | uniq -c | sort -rn
tee file표준 출력 + 파일 동시 저장ls | tee list.txt
split -l nn줄 단위로 파일 분할split -l 100 large.txt
wc -l/-w/-c줄수/단어수/바이트수 계산wc -l file.txt
sort -n/-r/-k숫자/역순/키 기준 정렬sort -k2 -n file

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤