パラメータが-で始まる場合にパラメータを送信する方法

パラメータが-で始まる場合にパラメータを送信する方法

「-」で始まらないパラメータに達するまで、「-」で始まるすべてのパラメータを削除する必要がある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たとえば、引数を使用し、そのオプションに長いオプションの別名と、そのオプションの--file2番目の別名を持つオプションをサポートします。--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
  • ワグ送信されたパラメータを示します。包装紙

便利に省略するには、オプション--に設定し、「スマート」チェックを試みる前に検索するだけです。

関連情報