Bash: So verwenden Sie while shift; do..case $1 in

Bash: So verwenden Sie while shift; do..case $1 in

Ich arbeite an einem Bash-Skript und muss „Optionen“ implementieren. Wie kann ich das mit Bash machen?

mein Ziel ist, das Skript folgendermaßen auszuführen: /myscript.sh -d "/var/log/" -c "test"

was ich versucht habe:

while shift; do
        case $1 in
                -d)
                        shift&&DIR="$1"||die
                ;;
                -c)
                        shift&&COMMAND="$1"||die
                ;;
        esac
done

echo "$DIR"
echo "$COMMAND"

Antwort1

Um die Antwort von @choroba zu erweitern, hier ein Beispiel zur Verwendung getopts:

# parse the flag options (and their arguments)
while getopts c:d: OPT; do
    case "$OPT" in
      d)
        DIR="$OPTARG" ;;
      c)
        COMMAND="$OPTARG" ;;
      [?])
        # got invalid option
        echo "Usage: $0 [-d directory] [-c command]" >&2
        exit 1 ;;
    esac
done

# get rid of the just-finished flag arguments
shift $(($OPTIND-1))

Beachten Sie, dass nach dem Verschieben der Flag-Argumente alle „normalen“ Argumente erhalten bleiben. An diesem Punkt können Sie sich also entweder mit ihnen befassen (z. B. ... for arg in "$@"; do ...) oder, wenn Ihr Skript sie nicht akzeptiert, einfach meckern, wenn Sie welche bekommen ( if [ $# -gt 0 ]; then echo "Usage ...).

Antwort2

Ihr Fehler besteht darin, dass Sie am Anfang der Schleife verschieben und das erste Argument wegwerfen, bevor Sie es untersucht haben. Ich denke, Sie haben wahrscheinlich Folgendes gemeint:

#!/bin/bash
while (( "$#" )); do
   case $1 in
      -d)
         shift&&DIR="$1"||die
         ;;
      -c)
         shift&&COMMAND="$1"||die
         ;;
   esac
   shift
done

echo "$DIR"
echo "$COMMAND"

Antwort3

Wie choroba bereits sagte,getoptsist ein besserer Ansatz.

In Ihrem Fall könnten Sie Folgendes verwenden:

getopts c:d: d || die
DIR=$OPTARG
getopts c:d: c || die
COMMAND=$OPTARG

um das zu erreichen, was Sie mit der While-Schleife versuchen.

Die Zeichenfolge c:d:gibt die möglichen Schalter an. Der Doppelpunkt bedeutet, dass der Schalter ein Argument erfordert.

Das Problem bei Ihrem Ansatz besteht darin, dass Sie aufrufen, shiftbevor Sie das erste Argument analysieren und es dabei verwerfen.

Um dies zu beheben, ändern Sie die While-Schleife wie folgt:

while true; do
        case $1 in
                -d)
                        shift&&DIR="$1"||die
                ;;
                -c)
                        shift&&COMMAND="$1"||die
                ;;
        esac
        shift || break
done

Antwort4

Der übliche Ansatz besteht darin, zu verwenden getopts.

verwandte Informationen