Bash Shell에서 Argument 다루는 법은 아주 쉽다.
$ test.sh A B C
위와 같이 사용자가 실행했을 경우, 순서대로 $1, $2, $3 으로 해당 값들을 가져올 수 있다.
#!/bin/bash
var_a=$1 # A
var_b=$2 # B
var_c=$3 # C
여러개의 파라미터를 한번에 배열 혹은 string 으로 받아오고 싶다면,
$@를 사용하면 손쉽게 가져올 수 있다.
#!/bin/bash
var_all_arr=("$@") # [A,B,C]
var_all_str=$@ # "A B C"
그렇다면 아래 명령어에서 /bin/bash -c python3 start.py
를 가져오려면 어떻게 해야할까?
$ test.py A B /bin/bash -c python3 start.py
쉽다! 배열로 받아온 후 앞에 두개를 제외하도록 slicing 하면 된다.
#!/bin/bash
var_all_arr=("$@")
var_cmd=${var_all_arr[@]:2} # 배열에서 2번째부터 끝까지 가져오기
들어온 Argument의 총 개수를 알고 싶다면 $#을 통해 가져오자.
#!/bin/bash
var_num=$#
Positional Argument의 경우 자리수대로 가져오면 쉬운데, cli를 만들다보면 아래와 같이 optional argument를 쓰고 help 함수들을 쓰게 된다.
$ test.sh -c 10 -v
이 경우에는 getopts를 이용해 작성해주면 된다.
#!/bin/bash
help(){
echo "Usage : $0 -c <count number> -v "
}
while getopts c:v opt
do
case $opt in
c)
var_count=$OPTARG
;;
r)
flag_verbose=true
;;
*)
help
exit 0
;;
esac
done
이 때, v 옵션의 경우 뒤에 값을 받지 않는 flag이므로 ':'없이 써주면된다.
$ test.sh -c 10 -f a.txt -v -d
$ test.sh -h
만약, 위의 경우에는 아래와 같이 while문을 작성해주면 된다.
...
while getopts c:f:vdh opt
do
...
만약 --help
와 같은 '--' 즉, long option을 사용해야할 경우 다음과 같이 작성해주면 된다.
#!/bin/bash
ARGS=$(getopt -o vdhc:f: --long verbose,debug,count:,file: -- "$@")
if [[ $? -gt 0 ]]; then
help
fi
eval set -- ${args}
while :
do
case $1 in
-v | --verbose) verbose=true ; shift ;;
-d | --debug) debug=true ; shift ;;
-h | --help) help ; shift ;;
-c | --count) count=$2 ; shift 2 ;;
-f | --file) file_path=$2 ; shift 2 ;;
--) shift; break ;;
*) >&2 echo Unsupported option: $1
help ;;
esac
done
처음에는 낯설기도하고 맨날 까먹었는데 하다보면 익숙해져서
작은 script 에도 getopt를 쓰고있는 나를 볼 수 있다.