Shell Programming

1) 개요

  • Shell Script는 Unix나 Linux, 또는 POSIX를 지원하는 macOS 등에서 사용되는 인터프리터 기반 스크립트 언어이다.
  • 리눅스나 유닉스 환경이 갖추어진 곳이라면 어디서든 실행할 수 있다.
  • 프로그래밍 언어와 비슷하게 변수, 반복문, 제어문 등을 지원한다.

작성

  • 확장자는 생략하거나 직접 정해서 사용해도 되지만, 관례상 .sh를 사용한다.
  • 파일 최상단에 #!/bin/bash 형태의 Shebang을 작성하여 실행 쉘 환경을 지정한다.
  • 작성예시 (name.sh)
#!/bin/bash
echo "사용자 이름: " $USER
echo "홈 디렉토리: " $HOME
exit 0
  • 실행
  • sh 명령으로 실행: sh 파일경로
  • 실행 권한 부여 후 실행: chmod +x name.sh
  • 스크립트 파일 없이 단일 명령어로 실행: echo "사용자 이름: " $USER; echo "홈 디렉토리: " $HOME

2) 변수

개요

  • 변수를 미리 선언할 필요가 없다.
  • 최초로 값을 할당할 때 변수가 자동 생성된다.
  • 대소문자를 구분하며, 관례적으로 대문자를 자주 사용한다.
  • 대입 연산자(=) 전후에 공백을 두면 안 된다.
  • 별도의 타입 지정이 없으며, 대입하는 값에 따라 문자열이나 숫자로 취급된다.
  • 공백이 포함된 문자열은 큰따옴표("")로 묶어야 한다.

변수 선언 및 출력

  • 변수를 참조할 때는 변수명 앞에 $를 붙인다.
  • 예시 (variable.sh)
#!/bin/bash

language=Korean
echo "I can speak $language"

산술 연산

  • 변수에 저장된 값은 기본적으로 문자열로 취급된다.
  • 산술 연산을 수행하려면 expr 키워드와 백틱(````) 또는 $(( )) 구조를 사용해야 한다.
  • expr 연산 시 항과 연산자 사이에 반드시 공백을 두어야 한다.
  • 수식 내 괄호() 및 곱하기 연산자*는 백슬래시(\)로 이스케이프해야 한다.
#!/bin/bash

num1=100
num2=$num1+200
echo $num2                  # 출력: 100+200
num2=`expr $num1 + 200`
echo $num2                  # 출력: 300
num4=`expr $num3 \* 3`
echo $num4                  # 출력: 900
  • 위치 매개변수 (Positional Parameters)
  • 스크립트 실행 시 전달되는 인자는 $숫자 형태의 매개변수에 할당된다.
  • 실행 예시: sh variable.sh -a --b
  • $0: variable.sh (실행 파일명)
  • $1: -a (첫 번째 인자)
  • $2: --b (두 번째 인자)
  • $*: 전체 인자 목록 (-a --b)
  • $@: 전체 인자 목록 (각 인자를 개별 단어로 취급)
  • $#: 전달된 매개변수의 총 개수
#!/bin/bash

echo "실행 파일 이름: <$0>"
echo "첫번째 파라미터: <$1> 두번째 파라미터: <$2>"
echo "전체 파라미터: <$*> 이고 개수: <$#>"

3) 함수

개요

  • 특정 동작을 수행하는 코드 블록으로, 코드 재사용을 위해 작성한다.
  • function 함수명() { ... } 또는 함수명() { ... } 형태로 선언한다.
  • 예시 (func.sh)
#!/bin/bash

function print() {
    echo "Hello"
}

print
  • sh 명령어 실행 시 호환성 문제가 발생할 수 있으므로 bash 명령으로 실행하거나, 실행 권한을 부여한 후 직접 실행(./func.sh)한다.

매개변수 및 변수 Scope

  • 함수 내에서도 위치 매개변수($1, $2 등)를 사용할 수 있다.
  • 전역 변수: 함수 외부에서 생성하며 스크립트 전역에서 접근 가능하다.
  • 지역 변수: 함수 내부에서 local 키워드로 선언하며, 함수 내부로 범위가 제한된다.
#!/bin/bash

globalvar="전역변수"
function print() {
    echo $globalvar
    local localvar="지역변수"
    echo $localvar
}
echo $globalvar
print
echo $localvar    # 출력되지 않음

특수 매개변수

  • $$: 현재 스크립트 또는 명령어의 프로세스 ID (PID)
  • $?: 최근에 실행된 명령/함수의 종료 상태 (0은 정상 종료)
  • $!: 최근 실행된 백그라운드 작업의 PID
  • $-: 현재 설정된 쉘 옵션 플래그

매개변수 확장 (Parameter Expansion)

  • 변수 뒤에 문자열을 이어 쓸 때에는 ${변수명}문자열 형태로 중괄호를 사용한다.
URL="www.example.com/"
echo "http://${URL}login"    # http://www.example.com/login

변수 초기화 확장자

  • ${var:-default}: var가 비어있거나 unset이면 default를 반환 (기존 변수 유지)
  • ${var:=default}: var가 비어있거나 unset이면 defaultvar에 할당 후 반환
  • ${var:?message}: var가 비어있거나 unset이면 message 출력 후 스크립트 종료
  • ${var:+alternative}: var에 값이 존재할 때만 alternative 반환

문자열 추출 및 길이

  • ${#var}: 문자열 길이 반환
  • ${var:offset}: offset 위치부터 시작하는 문자열 반환
  • ${var:offset:length}: offset 위치부터 length만큼 자른 문자열 반환
  • ${var: -length}: 뒤에서부터 length만큼 자른 문자열 반환 (마이너스 기호 앞 공백 필수)

패턴 삭제 및 경로 추출

  • ${var#pattern}: 앞에서부터 가장 먼저 일치하는 패턴 삭제
  • ${var##pattern}: 앞에서부터 가장 마지막으로 일치하는 패턴까지 삭제 (파일명 추출)
  • ${var%pattern}: 뒤에서부터 가장 먼저 일치하는 패턴 삭제 (확장자 제거)

치환 및 대소문자 변환

  • ${var/pattern/string}: 처음 일치하는 패턴을 string으로 변환
  • ${var//pattern/string}: 일치하는 모든 패턴을 string으로 변환
  • ${var^}: 첫 글자만 대문자로 변환
  • ${var^^}: 전체 문자열을 대문자로 변환
  • ${var,}: 첫 글자만 소문자로 변환
  • ${var,,}: 전체 문자열을 소문자로 변환

4) 조건문

  • if 문
  • 대괄호 [와 조건식 사이에는 반드시 공백이 존재해야 한다.
if [ 조건식1 ]
then
    수행할 내용
elif [ 조건식2 ]
then
    수행할 내용
else
    수행할 내용
fi
  • switch-case 문
case $변수 in
    값1)
        수행문1;;
    값2)
        수행문2;;
    *)
        기본 수행문;;
esac

5) 반복문

  • for 문
# 리스트/배열 순회
for 변수 in 값1 값2 값3
do
    수행할 내용
done

# C 언어 스타일
for ((i=0; i<3; i++))
do
    수행할 내용
done
  • while 문
num=0
while [ $num -lt 3 ]
do
    echo $num
    num=$((num+1))
done
  • 제어문 키워드: until, break, continue, return, exit

6) 연산자

문자열 연산자

  • -z: 문자열 길이가 0이면 참
  • -n: 문자열 길이가 0이 아니면 참

비교 연산자

  • 정수 비교: -eq, -ne, -gt, -ge, -lt, -le (>, < 기호 사용 시 (( )) 구문 필요)
  • 문자열 비교: =, ==, != (>, < 기호 사용 시 [[ ]] 구문 필요)

논리 연산자

  • AND: [ 조건1 -a 조건2 ], [ 조건1 ] && [ 조건2 ], [[ 조건1 && 조건2 ]]
  • OR: [ 조건1 -o 조건2 ], [ 조건1 ] || [ 조건2 ], [[ 조건1 || 조건2 ]]

파일 및 디렉토리 연산자

  • -d: 디렉토리이면 참
  • -e: 파일/디렉토리가 존재하면 참
  • -f: 일반 파일이면 참
  • -L: 심볼릭 링크이면 참
  • -r / -w / -x: 각각 읽기 / 쓰기 / 실행 권한이 있으면 참
  • -s: 파일 크기가 0보다 크면 참

파일 비교 연산자

  • 파일1 -nt 파일2: 파일1이 파일2보다 최신 파일이면 참
  • 파일1 -ot 파일2: 파일1이 파일2보다 오래된 파일이면 참
  • 파일1 -ef 파일2: 두 파일이 동일한 파일(하드 링크 등)이면 참

7) 내장 함수 (Built-in Functions)

  • eval: 문자열을 명령문으로 해석하여 실행한다.
  • export: 변수를 환경 변수로 등록하여 자식 프로세스에서도 참조 가능하게 한다.
  • printf: C 언어의 printf와 같이 서식화된 출력을 제공한다.
  • set: 명령어의 실행 결과를 파라미터($1, $2…)로 할당한다.
set $(date)
echo "$1"    # date 명령어 결과의 첫 번째 항목 출력

8) 정규 표현식 (Regular Expression)

개요

  • 특정한 규칙을 가진 문자열의 집합을 표현하는 형식 언어이다.
  • 대용량 텍스트에서 특정 패턴을 검색, 추출, 치환할 때 사용한다.

메타 문자

  • .: 임의의 한 문자 (줄바꿈 제외)
  • ^: 줄의 시작
  • $: 줄의 끝
  • |: OR 조건
  • *: 0회 이상 반복
  • +: 1회 이상 반복
  • ?: 0회 또는 1회 존재
  • {n} / {n,} / {n,m}: n회 반복 / n회 이상 반복 / n~m회 반복
  • [ ]: 대괄호 내 문자 중 하나와 매칭 (하이픈-은 범위 지정, ^는 부정)
  • ( ): 그룹화

POSIX 문자 클래스

  • [:digit:]: 숫자 ([0-9])
  • [:lower:] / [:upper:]: 소문자 / 대문자
  • [:alpha:] / [:alnum:]: 알파벳 / 알파벳 및 숫자
  • [:space:] / [:blank:]: 공백 전체 / 스페이스 및 탭
  • [:print:] / [:graph:]: 출력 가능 문자 (공백 포함 / 공백 제외)

grep 명령어 활용 예제

# C로 시작해서 U로 끝나는 3글자 단어 검색
grep C.U expression.txt

# q로 시작하고 ?로 끝나는 소문자 단어 검색
grep -E 'q[[:lower:]]*\?' expression.txt

# '-' 뒤에 숫자 2가 1회 이상 반복되고 '-'로 끝나는 패턴 검색
grep -E '\-2+\-' expression.txt

# 라인 시작 기준 영문 5글자 뒤에 공백이 오는 단어 검색
grep -E '^[a-zA-Z]{5}[[:space:]]' expression.txt

# 영문 4글자 이상 6글자 이하로 끝나는 단어 검색
grep -E '[a-zA-Z]{4,6}$' expression.txt