본문 바로가기

셸 스크립트에서 인자 입력 처리하기

기술적인 이야기/터미널 및 셸 2023. 12. 7.
반응형

셸 스크립트에서 인자(argument, 혹은 파라미터, parameter, 매개변수, 옵션 등) 입력을 받을 경우 스크립트 내에서는 어떻게 처리하는지 간단히 정리해 보는 글이다. 당연히 모든 경우를 다룰 수는 없고 개인적으로 자주 사용하는 몇 가지만 정리해 봤다. 사용하는 셸은 bash, zsh, sh다.

인자 입력 기본

셸 스크립트 내에서는 $N 같은 표기의 심벌로 인자 데이터에 접근할 수 있다. $0은 스크립트 자체의 이름, 1부터는 해당 순번의 인자가 문자열로 들어가게 된다. 그리고 각 인자는 공백문자로 구분된다.

예를 들어 아래와 같은 셸 스크립트 코드가 있다면

echo "0: $0"
echo "1: $1"
echo "2: $2"

위 내용의 코드를 sample.sh 파일로 저장한 다음 아래와 같이 실행시켜서 아래와 같은 결과를 얻을 수 있다.

$ bash sample.sh aaa bbb
0: sample.sh
1: aaa
2: bbb

위 내용에서 $는 셸 프롬프트이니 오해하지 말자.

참고로 기초적인 내용이지만 셸 스크립트 시작줄에 #!를 이용해 실행 프로그램을 명기해서 좀 더 편하게 실행시키는 방법도 있다. 예를 들어 위 스크립트를 아래와 같이 서두에 한 줄 추가해 주면

#!/bin/bash

echo "0: $0"
echo "1: $1"
echo "2: $2"

이후 실행 퍼미션을 부여해서 스크립트 이름만을 입력해서 실행시킬 수도 있다.

$ chmod a+x sample.sh
$ ./sample.sh aaa bbb
0: ./sample.sh
1: aaa
2: bbb

여담으로 셸 스크립트 실행 시 만약 해당하는 번호의 인자가 입력되지 않으면 그냥 빈 값이 출력된다.

$ ./sample.sh
0: ./sample.sh
1:
2:

모든 인자를 순회하기

입력된 모든 인자를 리스트 형태로 순회(iteration)하는 방법도 있다. $* 심벌을 이용하면 간단하다.

#!/bin/bash

for arg in $*
do
    echo "$arg"
done

이렇게 하면 아래와 같이 실행시켜서 결과를 얻을 수 있다.

$ ./sample.sh a b c
a
b
c

얼마나 활용이 될지는 잘 모르겠지만 이런 방법도 있다는 정도의 내용이다.

인자로 파일 경로 입력받기

제목이 뭔가 “응? 그냥 받으면 되잖아?”라고 할 수도 있는데, 이 항목의 주제는 와일드카드(wildcards)를 동원할 수 있는 방법이다. 이 경우 $@를 이용할 수 있는데 와일드카드를 쓰게 되면 파일이 하나 이상이 될 수도 있기에 리스트 형태로 쓸 수 있다. 예를 들어 아래의 코드를 sample.sh로 저장했다고 치자.

#!/bin/bash

for path in $@
do
    echo "$path"
done

이 코드를 이용해 와일드카드를 이용한 파일 경로를 입력해서 이런 결과를 얻을 수 있다.

$ ./sample.sh /etc/*.conf
/etc/asl.conf
/etc/autofs.conf
/etc/kern_loader.conf
/etc/man.conf
/etc/newsyslog.conf
/etc/nfs.conf
/etc/notify.conf
/etc/ntp.conf
/etc/ntp_opendirectory.conf
/etc/pf.conf
/etc/resolv.conf
/etc/rtadvd.conf
/etc/syslog.conf

/etc/*.conf의 의미는 /etc 디렉터리 아래에서 확장자가 .conf로 끝나는 모든 파일이라는 의미다. 그래서 상당히 많은 내용이 출력된다. 당연하게도 출력되는 내용은 사용자마다 다를 수 있다.

인자 리스트 시작 지점 바꾸기

좀 특수한 경우겠지만, 인자 리스트를 다루는 경우 특정 순서의 인자를 액세스 하기 난감해지는 경우도 있을 수 있다. 예를 들어 셸 스크립트가 위의 와일드카드를 이용할 수 있는 파일 경로를 인자로 입력받는데 이 외에도 몇 가지 인자를 앞에 더 붙여야 하는 경우를 생각해 보자. 어떻게 해야 할지 뭔가 감이 안 올 수 있다.

이럴 때를 위해서 shift를 이용할 수 있다. 예를 들어 아래의 코드를 보자.

#!/bin/bash

echo "arg1: $1"
echo "arg2: $2"

shift
shift

for path in $@
do
    echo "arg3: $path"
done

shift를 이용하면 리스트 시작점을 하나 뒤로 밀 수 있다. 즉 shift를 두 번 실행시켜 1번과 2번 인자를 따로 쓰고 3번부터 $@의 리스트로 넘어가게 하는 방식이다. 그래서 이런 식으로 쓸 수 있게 된다.

$ ./sample.sh first second /etc/*.conf
arg1: first
arg2: second
arg3: /etc/asl.conf
arg3: /etc/autofs.conf
arg3: /etc/kern_loader.conf
arg3: /etc/man.conf
arg3: /etc/newsyslog.conf
arg3: /etc/nfs.conf
arg3: /etc/notify.conf
arg3: /etc/ntp.conf
arg3: /etc/ntp_opendirectory.conf
arg3: /etc/pf.conf
arg3: /etc/resolv.conf
arg3: /etc/rtadvd.conf
arg3: /etc/syslog.conf

이런 식으로 1번가 2번 인자를 다른 옵션을 가리키는 용도로 쓰고 3번째 인자를 파일 경로로 입력받을 수 있었다.

실제로 터미널에서 실행시켜 본 모습

개인적으로는 이런 정도의 셸 스크립트 인자 처리 방법이 많이 사용되었었는데 물론 아주 간단한 경우에 한해서일 것이다. 기회가 된다면 좀 더 복잡한 인자 처리에 대해 정리할 수 있으면 좋겠다. 쉽진 않을 테니 말이다.

728x90
반응형

댓글