2

(いきなりですが、この質問は主に、手動で定義された配列に情報を適用getoptsする方法と a を適用する方法に関するものです。shift

getopts関数のパラメーターを通常の方法で解析しながら、予期しないパラメーター解析する (複数回処理をループすることによって)いくつかの Bash 関数を開始するための手順を作成しています。getopts

process_arguments()以下のコードでは、基本的にgetopts処理を含む小さな関数とshift、位置パラメータに作用する最終的な操作を見ることができます。このパラメーター解析の全体的な手順は、スクリプトではなく関数process_argumentsを対象としているため、関数に含まれる処理をスクリプトのメインwhileループに移動したいと考えています。これには、関数内のプロシージャからの入力および出力情報の変更が含まれます。

処理のための入力情報は、配列getoptsで渡すことができます:getoptsargs

getopts optstring name [args]

ただし、プロシージャの出力をどのように変更できるかはわかりません。現在、位置パラメーターをシフトしてから、位置パラメーターを出力します ( echo "${@}")。

それで、質問...

  • このgetopts argsアプローチは、プロシージャに情報を渡す正しい方法ですか?
  • shiftに渡されるパラメーターに を適用するにはどうすればよいgetoptsですか? また、これらのシフトされたパラメーターをスクリプトの残りの処理に出力するにはどうすればよいですか?

ご協力いただきありがとうございます。他のガイダンスを歓迎します。全体的な目標は、関数を削除し、process_arguments()その機能をメインの ``while``` ループに組み込むことです。

#!/bin/bash
################################################################################
#
# This is a test of command line parameter parsing that is explicitly non-POSIX.
# This approach handles
#     - options (for getopts)
#     - arguments of options (for getopts)
#     - positional arguments (for getopts) and
#     - non-option arguments (command line parameters not expected by getopts).
# All non-option arguments are placed in the string non_option_parameters. The
# silent error reporting mode of getopts is required. Following command line
# parameter parsing, input information can be accepted based on internal
# priority assumptions.
#
# example usage:
#     ./script.sh 
#         non-option parameters:
#     ./script.sh  -a Dirac
#         -a triggered with parameter Dirac
#         non-option parameters: 
#     ./script.sh -a Dirac -b
#         -a triggered with parameter Dirac
#         -b triggered
#         non-option parameters: 
#     ./script.sh -a Dirac Feynman -b
#         -a triggered with parameter Dirac
#         -b triggered
#         non-option parameters: Feynman 
#     ./script.sh -a Dirac Feynman Born -b
#         -a triggered with parameter Dirac
#         -b triggered
#         non-option parameters: Feynman Born 
#     ./script.sh -a Dirac Feynman Born Born -b
#         -a triggered with parameter Dirac
#         -b triggered
#         non-option parameters: Feynman Born
#     ./script.sh -a Dirac Feynman Born Born -b
#         -a triggered with parameter Dirac
#         -b triggered
#         non-option parameters: Feynman Born Born
#
################################################################################

process_arguments(){
    OPTIND=1
    while getopts "${option_string}" option; do
        case ${option} in
            a)
                echo "-a triggered with parameter "${OPTARG}"" >&2 # output to STDERR
                ;;
            b)
                echo "-b triggered" >&2 # output to STDERR
                ;;
            \?)
                echo "invalid option: -"${OPTARG}"" >&2 # output to STDERR
            ;;
        esac
    done
    shift $(expr ${OPTIND} - 1)
    echo "${@}"
}

option_string=":a:b"
non_option_parameters=""
parameters="${@}"
while [ ! -z "${parameters}" ]; do
    parameters="$(process_arguments ${parameters})"
    non_option_parameters="${non_option_parameters} "$(awk -F '[ \t]*-' '{print $1}' <<< "${parameters}")
    parameters=$(awk -F '[ \t]*-' 'NF > 1{print substr($0, index($0, "-"))}' <<< "${parameters}")
done
echo "non-option parameters:${non_option_parameters}"
4

2 に答える 2

1

私はあなたのコードを読むのに多くの時間を費やしませんでした。私はあなたに同意します。スクリプトの「メインレベル」でオプション処理を行い、スクリプトの位置パラメーターを直接操作できるようにします。

ここに書き直します:

#!/bin/bash

while getopts ":a:b" option; do
    case $option in
        a)
            echo "-a triggered with parameter $OPTARG" >&2
            ;;
        b)
            echo "-b triggered" >&2
            ;;
        :)
            echo "missing argument for option -${OPTARG}" >&2
            ;;
        \?)
            echo "invalid option: -${OPTARG}" >&2
            ;;
    esac
done
shift $(( OPTIND - 1 ))

echo "remaining arguments:"
for (( i=1; i<=$#; i++ )); do
    printf "%d: '%s'\n" $i "${!i}"
done

そして実際に:

$ bash ./opts.sh -a A -b B -c -d "foo bar" baz
-a triggered with parameter A
-b triggered
remaining arguments:
1: 'B'
2: '-c'
3: '-d'
4: 'foo bar'
5: 'baz'

「-c」および「-d」の「無効なオプション」エラーは表示されません。while getoptsこれは、最初の非オプション引数「B」に到達したときにループが終了したためです。


更新: getopts を複数回呼び出す:

extra_args=()

while (( $# > 0 )); do
    OPTIND=1
    while getopts ":a:b" option; do
        case $option in
            a) echo "-a triggered with parameter $OPTARG" >&2 ;;
            b) echo "-b triggered" >&2 # output to STDERR ;;
            :) echo "missing argument for option -$OPTARG" >&2 ;;
            ?) echo "invalid option: -$OPTARG" >&2 ;;
            esac
    done
    shift $(( OPTIND - 1 ))
    if (( $# > 0 )); then 
        extra_args+=( "$1" )
        shift
    fi
done

echo "non-option arguments:"
printf "%s\n" "${extra_args[@]}"
$ bash ~/tmp/opts.sh   -a A B -c -d "foo bar" baz -b
-a triggered with parameter A
invalid option: -c
invalid option: -d
-b triggered
non-option arguments:
B
foo bar
baz
于 2014-01-16T16:29:26.127 に答える