본문 바로가기
개발/linux

쉘 스크립트 문법

by 가시죠 2023. 3. 13.
반응형

변수

1. 대입할때는 $를 붙이지 않는다.

$appdir=/home/hitomis/myapp <- 에러

 

2. 양옆에 공백이 없어야 한다.

appdir = /home/hitomis/myapp <- 에러

 

3. 변수명은 영문자와 숫자, 언더바만 사용하며 숫자는 첫글자로 지정할 수 없다.

1appdir <- 에러

app-dir <- 에러

appdir=/home/hitomis/myapp <- 정상

 

명령어 치환

명령어의 출력 결과를 이용하고 싶을 경우 $() 같은 형식으로 작성

# 실행하면 현재날짜로 파일을 파일을 만든다
filename=$(date '+%Y-%m-%d')
touch $filename

 

위치파라메터

$ ./parameters.sh aaa bbb ccc

위 명령어에서 위치 파라메터는 아래와 같다.

./parameters.sh <- $0

aaa <- $1

bbb <- $2

ccc <- $3

#filename = parameters.sh

echo "\$0 = $0"
echo "\$1 = $1"
echo "\$2 = $2"
echo "\$3 = $3"
echo "\$4 = $4"

파일을 만들고 아래 처럼 실행하면..

$ ./parameters.sh aaa bbb ccc 

$0 = ./parameters.sh
$1 = aaa
$2 = bbb
$3 = ccc
$4 =

ps. 인자갯수는 $#으로 확인 할 수 있다.

 

[위치 파라메터 정리]

변수 내용
$0 쉘 스크립트 파일 이름
$1, $2, .... 커맨드 라인 인자의 값 (위치 파라메터)
$# 위치 파라메터 갯수
$@ 모든 위치 파라메터, 큰 따옴표로 감싸면 각각의 위치 파라메터가 큰 따옴표로 감싸짐
$* 모든 위치 파라메터, 큰 따옴표로 감싸면 전체가 하나의 문자열로 감싸짐

제어구조

if문

#filename : if-bin.sh

if [ "$1" = "bin" ]; then
	echo "OK"
else
	echo "NG"
fi

첫번째 인자값이 bin일 경우 OK를 출력하고 bin이 아닐경우 NG를 출력

 

if문 문법 주의사항

1. 조건식에 이어 세미콜론을 붙여야 한다. (단, 다음행에 입력 시 생략 가능)

   if [ "$1" = "bin" ] then <- 에러

   if [ "$1" = "bin" ] <- 정상

   then

2. [] 전후에 반드시 공백이 존재해야 한다.

   if ["$1" = "bin"] <- 에러

   if [ "$1" = "bin" ] <- 에러

   if [ "$1" = "bin" ] <- 정상

3. if 문 뒤에 오는 것은 조건식이 아니라 명령어이어야 한다.

# 제어문 if 기본 문법

if <명령어 1>; then
	<명령어 1>의 결과가 참일 경우 실행될 처리
elif <명령어 2>; then
	<명령어 2>의 결과가 참일 경우 실핼될 처리
elif <명령어 3>; then
	<명령어 3>의 결과가 참일 경우 실행될 처리
else
	위 명령어 모두 거짓일 경우 실행될 처리
fi

문자열 비교

연산자 설명
str1 = str2 str1과 str2가 같음
str1 != str2 str1과 str2가 같지 않음
-n str1 str1이 빈 문자열이 아님
-z str1 str1이 빈 문자열 임

예제

# 첫번째 인자값을 filename 변수에 넣고 인자값이 없을 경우 filename에 default.dat를 입력 후 출력

filename=$1

if [ -z $filename ]; then
        filename="default.dat"
fi

echo "filename is $filename"

정수 비교

연산자 설명
int1 -eq int2 int1과 int2가 같음
int1 -ne int2 int1과 int2가 같지 않음
int1 -lt int2 int1이 int2보다 작음
int1 -le int2 int1이 int2 이하임
int1 -gt int2 int1이 int2보다 큼
int1 -ge int2 int1이 int2 이상임

예제

# 인자값 2개를 받아서 큰 수를 표시

num1=$1
num2=$2
max=$num1

if [ "$num1" -lt "$num2" ]; then
	max=$num2
fi
echo "max num is $max"

파일속성

연산자 설명
-e file file이 존재함
-d file file이 존재하고 디렉터리임
-h file file이 존재하고 심볼릭 링크임
-L file file이 존재하며 심볼릭 링크임 (h와 동일)
-f file file이 존재하며 일반파일임
-r file file이 존재하며 읽기 권한이 부여되어 있음
-w file file이 존재하며 쓰기 권한이 부여되어 있음
-x file file이 존재하며 실행 권한이 부여되어 있음
file1 -nt file2 file1의 변경 시간이 file2보다 최근임
file1 -ot file2 file1의 변경 시간이 file2보다 오래됨

예제

# logdir 변수에 지정된 디렉터리가 존재하는지 -d ㄹ 확인하고 메시지 출력

logdir=/home/hitomis/myapp/logs

if [ -d "$logdir" ]; then
	echo "로그 디렉토리 : $logdir"
else
	echo "[error] 로그 디렉토리가 존재하지 않습니다. : $logdir"
fi

연산자 결합

연산자 설명
조건식1 -a 조건식2 조건식1과 조건식2가 모두 참
조건식1 -o 조건식2 조건식1과 조건식2 중 하나가 참이면 참
! 조건식 조건식이 거짓일 경우
() 조건식 그룹화

예제

# datadir이 디렉토리이고 읽기 권한이 부여되었는지 체크

if [ -d "$datadir" -a -r "$datadir" ]; then
	....
fi

&&와 ||

명령어를 순차적으로 평가할 수 있다.

명령어1 && 명령어2 처럼 입력하면 명령어1이 정상 종료하여 0이 반환된 경우에만 명령어2가 실행된다.

예제

# && 예제 - file.txt가 존재하면 cat 명령으로 내용을 출력

$ [ -f file.txt ] && cat file.txt

# || 예제 - file.txt가 존재하지 않으면 file.txt 파일을 만든다.
$ [ -f file.txt ] || touch file.txt

if문에서 && || 를 사용할 수 있다. 이때 일반 프로그램 처럼 && || 를 사용한다.

# 첫번째 인자를 int1에 넣고 3보다 크고 6보자 작을 경우 실행

int1=$1

if [ "$int1" -gt 3 ] && [ "$int1" -lt 6 ]; then
	echo "인자값은 3보다 크고 6보다 작다"
fi

 

for문

for 변수 in 리스트
do
    반복 처리
done
for name in aa bb cc
do
	echo $name
done
# 현재 디렉토리에서 *.html 파일을 찾아서 첫번째 행만 출력

for filename in *.html
do
	head -n 1 "$filename"
done

seq 명령을 이용한 for문 출력

#!1부터 5까지 출력

seq 1 5
#! seq 명령을 이용하여 0001.txt ~ 0005.txt 파일 생성

for i in $(seq 1 5)
do
	touch "000{i}.txt"
done
# for문으로 커맨드라인 인자를 처리
# 인자로 받은 값을 echo 로 화면에 출력

for param in "$@"  # <- in "$@" 생략가능 
do
	echo "$param"
done

# 위 내용과 동일
for param
do
	echo "$param"
done

 

case 문 - 문자열에 대한 처리는 for문 보다 편함

case <문자열> in
    <패턴 1>)
        처리 1
        ;;
    <패턴 2>)
        처리 2
        ;;
esac
# 인자값을 받아서 .txt 파일일 경우 less 명령어 실행
# .sh 파일일 경우 vim 명령어 실행

case "$1" in
	*.txt)
    	less "$1"
        ;;
    *.sh)
    	vim "$1"
		;;    
	*)
    	echo "not txt or sh file"
		;;
esac
# | 명령어로 or 조건 수행 하는 case 문

case "$1" in
	aaa | bbb) # aaa 또는 bbb 일 경우 ok 출력 아닐경우 error 출력
    	echo "ok"
        ;;
	*)
    	echo "error"
        ;;
esac

 

while문

while <명령어>
do
    반복처리
done
# 10 이하 홀수만 출력

i=1
while [ "$i" -le 10 ] # 10보다 작을 경우
do
    echo "$i"
    i=$((i+2)) # i변수에 2를 더한 후 i에 다시 대입 산술연산은 $((산술연산)) 형태로 사용
done

 

함수

function <함수이름> ()  <- 괄호 혹은 function 생략가능 (둘중에 하나만 생략가능)
{
    처리
}

위와 동일
function <함수이름>
{
    처리
}

위와 동일 - 가장 많이 사용하는 방식
<함수이름> ()
{
    처리
}

# 오늘 날짜를 출력하고 홈디렉토리의 디스크 사용량을 출력하는 함수 선언 후 호출

homesize()
{
	date
    du -h | tail -n 1
}

homesize
# 함수의 인자를 받아서 처리
# function_param.sh

print_param()
{
    echo "첫번째 = $1"  
    echo "두번째 = $2"
    echo "세번째 = $3"
    
    echo "$# 인자갯수"
    echo "파일명 = $0"    
}

print_param a b c

 

반응형

'개발 > linux' 카테고리의 다른 글

쉘 스크립트 괄호확장  (1) 2023.04.08
쉘 스크립트 활용  (0) 2023.04.08
bash 기초 - tar  (0) 2022.08.24
bash 기초 - du (disk usage)  (0) 2022.08.24
linux 표준파일시스템  (0) 2022.08.24

댓글