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이면 default를 var에 할당 후 반환
${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
case $변수 in
값1)
수행문1;;
값2)
수행문2;;
*)
기본 수행문;;
esac
5) 반복문
# 리스트/배열 순회
for 변수 in 값1 값2 값3
do
수행할 내용
done
# C 언어 스타일
for ((i=0; i<3; i++))
do
수행할 내용
done
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