「-」で始まらないパラメータに達するまで、「-」で始まるすべてのパラメータを削除する必要があるbash関数があるとします。
gmx(){
local options=( );
while [ "${1:0:1}" == "-" ]; do
options+=("${1}")
shift 1;
done
echo "first legit arg: $1"
"$@" # omg will be executed here, like `omg --rolo`
}
gmx -a -f -c omg --rolo
これはうまくいくようですが、これが常に「omg」を最初の「法的」パラメータとして置くための良い一般的な解決策であると思います。失敗する可能性がある極端なケースはありますか?
つまり、-a、-f、-cはすべてgmxのパラメータです。そしてomg
それに続くすべては子プロセスで実行されます。
答え1
正式で最善の方法は、getopts
組み込み関数を使用してコマンドラインオプションを解析しないことです。
詳しくはマニュアルページをご覧ください。
注意事項が重要な場合があります。bash
長いオプションはサポートされていません。
長いオプションを処理するためにスクリプトを好む場合は、それksh93
をサポートする2つのシェルがあります。bosh
両方のシェルは、getopt(3)
Solarisのlibc関数が長いオプションをサポートしているかのように長いオプションをサポートします。 boshのマニュアルページ(現在の43ページから始まる)を参照してください。
http://schilytools.sourceforge.net/man/man1/bosh.1.html
getopts "f:(file)(input-file)o:(output-file)" OPT
-f
たとえば、引数を使用し、そのオプションに長いオプションの別名と、そのオプションの--file
2番目の別名を持つオプションをサポートします。--input-file
ksh93もこれをサポートしますが、ksh93のマニュアルページには文書化されていません。
答え2
while getopts ':' opt; do
: # This is where ordinarily a case statement would be,
# case $opt in ... esac
# But we use : as a no-op
done
shift "$(( OPTIND - 1 ))"
printf 'arg: %s\n' "$@"
getopts
これはコマンドラインオプションを解析するために使用されます。while
最初の非オプションが見つかると、ループは終了し、処理されshift
たオプションは削除され、オプションでは$@
なくオペランドのみが残ります$@
。
スクリプト
#!/bin/sh
gmx () {
while getopts ':' opt; do
:
done
shift "$(( OPTIND - 1 ))"
printf 'arg: %s\n' "$@"
}
gmx -a --foo -c omg lol
出力されます
arg: omg
arg: lol
実際のオプションには興味がないので、次の簡単なループを実行できます。
for opt do
case $opt in
-*) shift ;;
*) break
esac
done
printf 'arg: %s\n' "$@"
これは、すべてのパラメータを繰り返してダッシュで始まる各パラメータを削除し、ダッシュで始まらない最初のパラメータで終わります。
答え3
方法を制御できる場合は、より簡単なソリューションGMX--
呼び出され、ラッパーの引数をラップされたコマンドから次のように分離するために使用されます。
gmx garg garg garg -- warg warg warg
どこ
- ガルグ使用されたパラメータを示します。GMX。
- ワグ送信されたパラメータを示します。包装紙。
便利に省略するには、オプション--
に設定し、「スマート」チェックを試みる前に検索するだけです。