bash 에서 옵션 처리를 할 경우, bash 의 내장 함수인 getopts 또는 GNU getopt 를 사용하게 되는데, 필자의 경우에는 long option 을 제공하는 GNU getopt 를 더 선호하는 편입니다.
하지만 GNU getopt 를 사용할 경우 치명적인 문제가 하나 있는데, 바로 옵션 값에 공백 문자가 있을 경우, getopt -> set 을 하는 과정에서 옵션 값의 공백문자를 기준으로 분리가 되어 버리는 문제 입니다. (set 을 하는 이유는, 옵션과 인자값 순서를 섞어도 되게 하기 위해서 입니다.) 예를 들어
#!/bin/bash
opts="$( getopt -o h -u -l help -- $@ )"
set -- ${opts}
echo "$@"
echo "$3"
와 같이 코드를 만들고, 실행을 하면 다음과 같이 출력이 됩니다.[user@host ~]$ bash test.sh -h "1 2 3"
-h -- 1 2 3
1
출력되는 $3 은 기대하는 "1 2 3" 이 아니라 "1" 이 됩니다.그래서 이 문제는 해결하기 위해서는 다음과 같이 해 볼 수 있습니다.
#!/bin/bash
for i
do
[[ $i =~ [[:space:]] ]] && opt[n++]="\"${i}\"" || opt[n++]="${i}"
done
echo "input: ${opt[@]}"
opts="$( eval getopt -o ah: -l aa,hhh: -- ${opt[@]} )"
echo "opts -> ${opts}"
eval set -- ${opts}
for i
do
case "${i}" in
-a|--aa)
A=1
shift
;;
-h|--hhh)
H="${2}"
shift 2
;;
--)
shift;
break
esac
done
echo "$@"
echo "----"
echo "-h -> $H"
echo "\$1 -> $1"
echo "\$2 -> $2"
echo "\$3 -> $3"
echo "\$4 -> $4"
결과는[user@host ~]$ bash test.sh "123 456" -h '\"abc def\"' 789
input: -h "\"abc def\"" "123 456" 789
opts -> -h '"abc def"' -- '123 456' '789'
123 456 789
----
-h -> "abc def"
$1 -> 123 456
$2 -> 789
$3 ->
$4 ->
--
코드를 조금 더 업데이트 해 보았습니다. 옵션값이 quote 를 사용할 떄 escape 를 해야 했는데 불편해서 하지 않아도 되도록 개선해 보았습니다. 이 이슈 때문에 getopt 를 eval 을 했었는데 굳이 하지 않아도 되었더군요. ㅠ
#!/bin/bash
echo "input: $@"
opts="$( getopt -o ah: -l aa,hhh: -- "$@" )"
echo "opts -> ${opts}"
eval set -- "${opts}"
echo "input -> ${opts}"
for i
do
case "${i}" in
-a|--aa)
A=1
shift
;;
-h|--hhh)
H="${2}"
shift 2
;;
--)
shift;
break
esac
done
echo "$@"
echo "----"
echo "-h -> $H"
echo "\$1 -> $1"
echo "\$2 -> $2"
echo "\$3 -> $3"
echo "\$4 -> $4"
이렇게 하면 옵션값에 quote 를 사용할 때 escape 를 하지 않아도 됩니다.[user@host ~]$ bash test.sh 123\ 456 -h '"abc def"' 789
iinput: 123 456 -h "abc def" 789
opts -> -h '"abc def"' -- '123 456' '789'
input -> -h '"abc def"' -- '123 456' '789'
123 456 789
----
-h -> "abc def"
$1 -> 123 456
$2 -> 789
$3 ->
$4 ->
Comments List
2008년 가볍고 터미널 기반의 리눅스로 안녕 리눅스 접하고 한 5년간 서버도 운영해 보고 IDC에 넣어서 운영도 하고.. 웹사이트 운영해도 아르바이트도 하고. 개인적으론 아주 고마운 안녕 리눅스 였습니다. 지금은 비록 관련 분야에서 일을 하지 않지만 문득 생각이나서 안녕리눅스 타고 여기까지 왔습니다. 안녕리눅스 사이트가 아직까지 운영됨에 고마움과 개발자님의 리눅스 사랑에 대한 진심이 느껴집니다. 감사합니다.
진짜.... 1년넘게 중지 되는거 아니지요???
ㅎㅎ 1년 쉬고 싶었나 봐요. 그럴 때도 되지 않았나