オプションのオプションを持つフラグを持つスクリプトを作成しようとしています。getopts では、フラグの後に (コロンを使用して) 必須の引数を指定することができますが、オプションのままにしておきたいと思います。
次のようになります。
./install.sh -a 3
また
./install.sh -a3
ここで、「a」はフラグで、「3」は a に続くオプションのパラメーターです。
前もって感謝します。
外部プログラムではgetopt
、オプション名にダブルコロンを追加することで、オプションに単一のオプション引数を持たせることができます。
# Based on a longer example in getopt-parse.bash, included with
# getopt
TEMP=$(getopt -o a:: -- "$@")
eval set -- "$TEMP"
while true ; do
case "$1" in
-a)
case "$2" in
"") echo "Option a, no argument"; shift 2 ;;
*) echo "Option a, argument $2"; shift 2;;
esac ;;
--) shift; break ;;
*) echo "Internal error!"; exit 1 ;;
esac
done
以下はなしgetopt
で、-a フラグを使用してオプションの引数を取ります。
for WORD; do
case $WORD in
-a?) echo "single arg Option"
SEP=${WORD:2:1}
echo $SEP
shift ;;
-a) echo "split arg Option"
if [[ ${2:0:1} != "-" && ${2:0:1} != ""]] ; then
SEP=$2
shift 2
echo "arg present"
echo $SEP
else
echo "optional arg omitted"
fi ;;
-a*) echo "arg Option"
SEP=${WORD:2}
echo $SEP
shift ;;
-*) echo "Unrecognized Short Option"
echo "Unrecognized argument"
;;
esac
done
他のオプション/フラグも簡単に追加できます。
私の解決策:
#!/bin/bash
count=0
skip=0
flag="no flag"
list=($@) #put args in array
for arg in $@ ; do #iterate over array
count=$(($count+1)) #update counter
if [ $skip -eq 1 ]; then #check if we have to skip this args
skip=0
continue
fi
opt=${arg:0:2} #get only first 2 chars as option
if [ $opt == "-a" ]; then #check if option equals "-a"
if [ $opt == $arg ] ; then #check if this is only the option or has a flag
if [ ${list[$count]:0:1} != "-" ]; then #check if next arg is an option
skip=1 #skip next arg
flag=${list[$count]} #use next arg as flag
fi
else
flag=${arg:2} #use chars after "-a" as flag
fi
fi
done
echo $flag
bash には、いくつかの暗黙の変数があります。
$#: contains number of arguments for a called script/function
$0: contains names of script/function
$1: contains first argument
$2: contains second argument
...
$n: contains n-th argument
例えば:
#!/bin/ksh
if [ $# -ne 2 ]
then
echo "Wrong number of argument - expected 2 : $#"
else
echo "Argument list:"
echo "\t$0"
echo "\t$1"
echo "\t$2"
fi
getopt 機能を使用します。ほとんどのシステムでman getopt
は、ドキュメントが生成され、スクリプトでの使用例も生成されます。私のシステムのmanページから:
次のコード フラグメントは、オプション -a と -b、および引数を必要とするオプション -o を使用できるコマンドの引数を処理する方法を示しています。
args=`getopt abo: $*`
# you should not use `getopt abo: "$@"` since that would parse
# the arguments differently from what the set command below does.
if [ $? != 0 ]
then
echo 'Usage: ...'
exit 2
fi
set -- $args
# You cannot use the set command with a backquoted getopt directly,
# since the exit code from getopt would be shadowed by those of set,
# which is zero by definition.
for i
do
case "$i"
in
-a|-b)
echo flag $i set; sflags="${i#-}$sflags";
shift;;
-o)
echo oarg is "'"$2"'"; oarg="$2"; shift;
shift;;
--)
shift; break;;
esac
done
echo single-char flags: "'"$sflags"'"
echo oarg is "'"$oarg"'"
このコードは、次のいずれも同等のものとして受け入れます。
cmd -aoarg file file
cmd -a -o arg file file
cmd -oarg -a file file
cmd -a -oarg -- file file