프로그램을 실행할 때 인자(매개변수)를 전달하듯, 쉘 스크립트 역시 인자를 전달하여 실행할 수 있다.

이때, 스크립트 내에서 해당 인자를 받았을 때 처리하는 로직이 필요한데, 그러한 로직을 짤 때, '$'가 다양하게 쓰일 수 있다! 아래는 'test.sh' 라는 쉘 스크립트 파일을 실행하면서 a,b,c,d 라는 인자를 준 상황이다.

./test.sh a b c d

# './test.sh' 가 $0에 해당.
# 'a' 가 $1에 해당.
# 'b' 가 $2에 해당.
# 'c' 가 $3에 해당.
# 'd' 가 $4에 해당.

 

쉘 스크립트에서의 '$' 의 활용 - 위치 매개 변수(Positional Parameters)

종류 설명
$0 실행된 쉘 스크립트의 메인 구문
$1 스크립트에 넘겨진 첫 번째 아규먼트
$2 스크립트에 넘겨진 두 번째 아규먼트
$N(숫자) 해당 숫자에 해당하는 N 번째 아규먼트
$# 아규먼트의 개수를 의미
$* 스크립트에 전달된 인자 전체를 하나의 변수에 저장하면, IFS 변수의 첫 번째 문자로 구분된 결과를 의미.
$@ $*와 동일하지만, IFS환경변수를 사용 X
$! 실행을 위해 백그라운드로 보내진 마지막 프로그램 프로세스 번호
$$ 쉘 스크립트의 PID
$? 바로 이전 스크립트 또는 명령문 실행 뒤의 반환 값 (백그라운드로 실행된 것은 제외)

실제 쉘 스크립트의 실행을 통해 어떻게 동작하는지 살펴보자!

#! /bin/sh
# 해당 쉘 스크립트의 파일 명 : test_junho.sh

echo "##############################"
echo
echo -e "main_command(\$0) : $0"
echo -e "\$1 : $1"
echo -e "\$2 : $2"
echo -e "\$# : $#"
echo -e "\$* : $*"
echo -e "\$@ : $@"
echo -e "\$$ : $$"

echo "##############################"

위 쉘 스크립트의 디렉토리로 이동하여 실행 명령으로 './test_junho.sh a b c' 를 입력하면 아래와 같은 결과를 확인할 수 있다.

위 결과를 보면 위치 매개 변수가 무엇을 의미하는지 대강 알 수 있을 것이다.

그런데 여전히 $*, $@, $! 등은 잘 이해가 가지 않을 수 있다. for 문을 활용한 아래 예시를 보며, 구체적으로 확인해보자!


1) $* 을 for문에서 사용한다면?

#! /bin/sh

set 'a b' c d		# 이 쉘 스크립트의 실행 매개변수를 'a b', 'c', 'd' 로 지정.

echo "##############################"
echo
echo -e "What is '\$*'"		# \ 는 이스케이프 문자

n=1
for i in $*		# '$*' 를 그대로 사용하였을 때.
do
	echo "for #$n : $i"
    n=$((n + 1))
done

echo
echo "##############################"
echo
echo -e "Using Double Quotation -> \"\$*\"" 	# \ 는 이스케이프 문자

n=1
for i in "$*"		# 큰 따옴표를 사용한 "$*" 의 활용 
do
	echo "for #$n : $i"
    n=$((n + 1))
done

echo
echo "##############################"

우선 $* 는 매개변수를 받은 것들을 모두 한 변수에 넣고 IFS로 구분하게 된다. 즉, $*를 기준으로 for문을 수행하면, IFS의 디폴트값인 공백을 기준으로 매개변수를 쪼개어 하나씩 for문을 수행하게 된다. .

 그런데 큰 따옴표를 사용하여 "$*" 를 기준으로 for문을 수행하면, 각 매개변수들을 모두 이어 붙인 것을 하나의 문자열로 인식하기 때문에, 아래 결과처럼 for 문이 한 번만 수행되게 되는 것이다.

 

2) $@ 을 for문에서 사용한다면?

#! /bin/sh

set 'a b' c d		# 이 쉘 스크립트의 실행 매개변수를 'a b', 'c', 'd' 로 지정.

PRE_IFS=$IFS
IFS=':' 		# IFS를 : 로 변경 -> ':' 를 구분자로 사용하겠다.

echo "##############################"
echo
echo -e "What is '\$@'"		# \ 는 이스케이프 문자

n=1
for i in $@		# '$@' 를 그대로 사용하였을 때.
do
	echo "for #$n : $i"
    n=$((n + 1))
done

echo
echo "##############################"
echo
echo -e "Using Double Quotation -> \"\$@\"" 	# \ 는 이스케이프 문자

n=1
for i in "$@"		# 큰 따옴표를 사용한 "$@" 의 활용 
do
	echo "for #$n : $i"
    n=$((n + 1))
done

IFS=$PRE_IFS		# IFS 원상 복구 (반드시 해주어야 함.)
echo
echo "##############################"

$@$*와 동작 방식은 거의 같지만, 한 가지 차이점으로 IFS를 사용하지 않는다고 하였다. $@ 는 IFS를 사용하는 것이 아닌, 매개변수를 입력하는 시점에서의 공백 기준으로 자르기 때문에 아래와 같은 실행 결과가 나타난다. 

 또한 큰 따옴표를 쓴 "$@" 의 경우에서도, 큰 따옴표의 유무와 관련 없이 $@의 동작을 그대로 수행하게 된다.

3) $! 확인 방법

#! /bin/sh

echo "##############################"
echo
echo -e "What is '\$!'" 	# \ 는 이스케이프 문자
echo

echo -e "This process's PID : $$"

sleep 10
echo "After 10 seconds, finished!!"
echo -e "\$! : $!"

echo
echo "##############################"

위 스크립트를 수행할 때, 스크립트의 디렉토리로 가서 '/test_junho.sh &' 로 입력하여 백그라운드로 실행시켜 주면, 

해당 스크립트로 실행된 프로세스의 PID($$의 결과)25512 인 것을 확인할 수 있다.

여기서 주의할 점은, 이 스크립트가 실행되는 동안(백그라운드)의 $! 값을 조회하면 아무것도 나타나지 않는 반면,

해당 스크립트의 백그라운드 실행을 빠져나와서 'echo $!' 를 입력하면, 해당 프로세스의 PID인 25512 를 확인하 수 있게 된다는 것이다.

 

4) $? 의 사용

 만약 명령어가 실패할 경우 동작을 다르게 하려고 한다면, 스크립트에서는 어떻게 구현해야 할까?

이때 사용하는 것이 $? 이다. $? 는 가장 최근 실행한 명령어의 종료 코드 값이 들어있다. 정상적인 종료는 0으로 반환되며, 리눅스의 일반 명령어의 경우, 비정상 종료가 되면 1을 반환한다. 그 밖의 다른 프로그램의 경우에는, 해당 프로그램에서 설정된 exit(n) 구문에서의 n 값과 같은 종료 코드 값이 들어가게 된다.

#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[]){
	if(argc<2) {
    	fprintf(stderr, "인자는 2개 이상이어야 합니다.\n");
        exit(16);
    }
}

다음 예시를 통해 살펴보자. 위와 같은 c언어로 작성된 프로그램(main.c)이 있다고 생각해보자.

그리고 아래의 쉘 스크립트를 수행한다고 보자.

#! /bin/bash

function func() {
	./a.out		# 위 C언어로 작성된 프로그램이 컴파일된 파일을 실행하는데, 파라미터 2개를 넘겨주지 않음.
    echo "오류 코드 : $?"
}

# 함수 호출
func

위 쉘 스크립트를 수행하게 되면, C언어에서 설정한 종료코드인 16을 출력하는 것을 확인할 수 있을 것이다!


참고

https://inpa.tistory.com/entry/LINUX-%EC%89%98-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%95%B5%EC%8B%AC-%EB%AC%B8%EB%B2%95-%EC%B4%9D%EC%A0%95%EB%A6%AC

 

[LINUX] 📚 BASH 쉘 프로그래밍 문법 마스터 💯 총정리 (+ 연습예제)

Shell Script 란 Shell Script는 Shell이나 command line 인터프리터에서 구동되도록 작성된 스크립트다. 윈도우에서는 batch(배치파일, .bat) 을 한번쯤은 본적이 있을 것이다. bat 파일을 실행하면 프로그램..

inpa.tistory.com

https://bebeya.tistory.com/2696

 

쉘 스크립트(Shell Script) - 위치 매개 변수[$0, $1, $*, $@, $#]

쉘스크립트(Shell Script) 위치매개변수인 $0, $1, $*, $@, $# 사용법에 대해서 알아보자 위치 매개 변수(Positional Parameters) 문자 설명 $0 실행된 스크립트 이름 $1 $1 $2 $3...${10}인자 순서대로 번호가..

bebeya.tistory.com

https://reakwon.tistory.com/136

 

[리눅스] 쉘 스크립트(Shell script) 기본 문법, 작성방법(변수,반복문,비교문,종료상태 등)

쉘스크립트 기본 쉘 스크립트는 쉘에게 무슨 명령들을 실행할지 알려주는 스크립트 파일입니다. 여기서는 가장 널리쓰이는 bash 쉘을 사용하는 스크립트를 설명하도록 하겠습니다. #!/bin/bash 스

reakwon.tistory.com

https://jhnyang.tistory.com/153

 

[Linux/Unix/Shell programming] 위치 매개 변수, 특수매개변수, 아규먼트 변수 종류

[ 리눅스 / 유닉스 / 셸 스크립트 프로그래밍 목차 ] 안녕하세요~ 저번 포스팅에서 리눅스 유닉스의 변수에 대한 전체 개념을 잡아봤었는데요 ㅎㅎ 변수들의 종류 중 위치 매개변수에 대해서 설

jhnyang.tistory.com

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기