591 Stimmen

Ein Beispiel dafür, wie man getopts in bash verwendet

Ich möchte die Datei myscript auf diese Weise aufrufen:

$ ./myscript -s 45 -p beliebiger_string

oder

$ ./myscript -h  # Soll Hilfe anzeigen
$ ./myscript     # Soll Hilfe anzeigen

Meine Anforderungen sind:

  • getopt hier, um die Eingabeargumente zu erhalten
  • Überprüfen, ob -s existiert, falls nicht eine Fehlermeldung ausgeben
  • Überprüfen, ob der Wert nach dem -s 45 oder 90 ist
  • Überprüfen, ob -p existiert und ob danach ein Eingabestring vorhanden ist
  • Wenn der Benutzer ./myscript -h oder einfach nur ./myscript eingibt, dann Hilfe anzeigen

Ich habe bisher diesen Code versucht:

#!/bin/bash
while getopts "h:s:" arg; do
  case $arg in
    h)
      echo "Verwendung" 
      ;;
    s)
      strength=$OPTARG
      echo $strength
      ;;
  esac
done

Aber mit diesem Code erhalte ich Fehler. Wie kann ich das mit Bash und getopt machen?

762voto

Adrian Frühwirth Punkte 38808
#!/bin/bash

usage() { echo "Verwendung: $0 [-s <45|90>] [-p ]" 1>&2; exit 1; }

while getopts ":s:p:" o; do
    case "${o}" in
        s)
            s=${OPTARG}
            ((s == 45 || s == 90)) || usage
            ;;
        p)
            p=${OPTARG}
            ;;
        *)
            usage
            ;;
    esac
done
shift $((OPTIND-1))

if [ -z "${s}" ] || [ -z "${p}" ]; then
    usage
fi

echo "s = ${s}"
echo "p = ${p}"

Beispiel läuft:

$ ./myscript.sh
Verwendung: ./myscript.sh [-s <45|90>] [-p ]

$ ./myscript.sh -h
Verwendung: ./myscript.sh [-s <45|90>] [-p ]

$ ./myscript.sh -s "" -p ""
Verwendung: ./myscript.sh [-s <45|90>] [-p ]

$ ./myscript.sh -s 10 -p foo
Verwendung: ./myscript.sh [-s <45|90>] [-p ]

$ ./myscript.sh -s 45 -p foo
s = 45
p = foo

$ ./myscript.sh -s 90 -p bar
s = 90
p = bar

268voto

kenorb Punkte 134883

Das Problem mit dem ursprünglichen Code ist, dass:

  • h: erwartet einen Parameter, wo es keinen geben sollte, also ändern Sie es einfach in h (ohne Doppelpunkt)
  • um -p beliebiger_string zu erwarten, müssen Sie p: zur Argumentliste hinzufügen

Grundsätzlich bedeutet : nach der Option, dass ein Argument erforderlich ist.


Die grundlegende Syntax von getopts lautet (siehe: man bash):

getopts OPTSTRING VARNAME [ARGS...]

wo:

  • OPTSTRING ist ein String mit einer Liste der erwarteten Argumente,

    • h - überprüfen Sie die Option -h ohne Parameter; gibt einen Fehler bei nicht unterstützten Optionen aus;

    • h: - überprüfen Sie die Option -h mit Parameter; gibt Fehler bei nicht unterstützten Optionen aus;

    • abc - überprüfen Sie die Optionen -a, -b, -c; gibt Fehler bei nicht unterstützten Optionen aus;

    • :abc - überprüfen Sie die Optionen -a, -b, -c; unterdrückt Fehler bei nicht unterstützten Optionen;

      Hinweis: Mit Doppelpunkt vor den Optionen können Sie die Fehler in Ihrem Code behandeln. Die Variable enthält ? im Falle einer nicht unterstützten Option, : im Falle eines fehlenden Werts.

  • OPTARG - wird auf den aktuellen Argumentwert gesetzt,

  • OPTERR - zeigt an, ob Bash Fehlermeldungen anzeigen soll.

Der Code kann also sein:

#!/usr/bin/env bash
usage() { echo "$0 Verwendung:" && grep " .) #" $0; exit 0; }
[ $# -eq 0 ] && usage
while getopts ":hs:p:" arg; do
  case $arg in
    p) # Wert für p angeben.
      echo "p ist ${OPTARG}"
      ;;
    s) # Stärke angeben, entweder 45 oder 90.
      strength=${OPTARG}
      [ $strength -eq 45 -o $strength -eq 90 ] \
        && echo "Die Stärke beträgt $strength." \
        || echo "Die Stärke muss entweder 45 oder 90 betragen, anstelle von $strength."
      ;;
    h | *) # Hilfe anzeigen.
      usage
      exit 0
      ;;
  esac
done

Beispielverwendung:

$ ./foo.sh 
./foo.sh Verwendung:
    p) # Wert für p angeben.
    s) # Stärke angeben, entweder 45 oder 90.
    h | *) # Hilfe anzeigen.
$ ./foo.sh -s 123 -p beliebiger_string
Die Stärke muss entweder 45 oder 90 betragen, 123 gefunden.
p ist beliebiger_string
$ ./foo.sh -s 90 -p beliebiger_string
Die Stärke beträgt 90.
p ist beliebiger_string

Siehe: Kleines getopts-Tutorial beim Bash Hackers Wiki

201voto

theBuzzyCoder Punkte 2394

Verwenden Sie getopt

Warum getopt?

Um komplexe Befehlszeilenargumente zu analysieren, um Verwirrung zu vermeiden und die Optionen zu klären, die wir analysieren, damit der Leser der Befehle verstehen kann, was passiert.

Was ist getopt?

getopt wird verwendet, um Optionen in Befehlszeilen aufzuteilen (zu analysieren), damit sie von Shell-Prozeduren einfach analysiert werden können und um auf legale Optionen zu überprüfen. Hierbei werden die GNU-getopt(3)-Routinen verwendet.

getopt kann folgende Arten von Optionen haben.

  1. Optionen ohne Wert
  2. Schlüssel-Wert-Paar-Optionen

Hinweis: In diesem Dokument, bei der Erklärung der Syntax:

  • Alles innerhalb von [ ] ist ein optionales Parameter in der Syntax/Beispielen.
  • ist ein Platzhalter, der bedeutet, dass er durch einen tatsächlichen Wert ersetzt werden sollte.

WIE MAN getopt BENUTZT?

Syntax: Erste Form

getopt OptString Parameter

Beispiele:

# Das ist korrekt
getopt "hv:t::" -v 123 -t123  
getopt "hv:t::" -v123 -t123  # -v und 123 haben keinen Leerzeichen

# -h hat keinen Wert.
getopt "hv:t::" -h -v123

# Das ist falsch. Nach -t darf kein Leerzeichen stehen.
# Nur optionale Parameter dürfen kein Leerzeichen zwischen Schlüssel und Wert haben
getopt "hv:t::" -v 123 -t 123

# Mehrere Argumente, die einen Wert haben.
getopt "h:v:t::g::" -h abc -v 123 -t21

# Mehrere Argumente ohne Wert
# Alle diese sind korrekt
getopt "hvt" -htv
getopt "hvt" -h -t -v
getopt "hvt" -tv -h

Hier sind h,v,t die Optionen und -h -v -t ist die Art und Weise, wie Optionen in der Befehlszeile angegeben werden sollen.

  1. 'h' ist eine Option ohne Wert.
  2. 'v:' bedeutet, dass die Option -v einen Wert hat und ist eine obligatorische Option. ':' bedeutet hat einen Wert.
  3. 't::' bedeutet, dass die Option -t einen Wert hat, aber optional ist. '::' bedeutet optional.

Bei optionalen Parametern darf der Wert keine Leerzeichen-Trennung mit der Option haben. So ist im Beispiel "-t123" -t die Option und 123 der Wert.

Syntax: Zweite Form

getopt [getopt_optionen] [--] OptString Parameter

Hier wird getopt in fünf Teile aufgeteilt

  • Der Befehl selbst, d.h. getopt
  • Die getopt_optionen, sie beschreiben, wie die Argumente analysiert werden sollen. einstrichigen Langoptionen, doppelstrichigen Optionen.
  • --, trennt die getopt_optionen von den zu analysierenden Optionen und den erlaubten Kurzoptionen
  • Die Kurzoptionen werden unmittelbar nach dem gefundenen -- genommen. Genauso wie bei der ersten Form-Syntax.
  • Die Parameter, das sind die Optionen, die Sie dem Programm übergeben haben. Die Optionen, die Sie analysieren und deren tatsächliche Werte festlegen möchten.

Beispiele

getopt -l "name:,version::,verbose" -- "n:v::V" --name=Karthik -version=5.2 -verbose

Syntax: Dritte Form

getopt [getopt_optionen] -o|--optionen OptString [getopt_optionen] [--] [Parameter]

Hier wird getopt in fünf Teile aufgeteilt

  • Der Befehl selbst, d.h. getopt
  • Die getopt_optionen, sie beschreiben, wie die Argumente analysiert werden sollen. einstrichige Langoptionen, doppelstrichige Optionen.
  • Die Kurzoptionen, d.h. -o oder --options. Genauso wie bei der ersten Form-Syntax, aber mit der Option "-o" und vor dem "--" (doppelter Strich).
  • --, trennt die getopt_optionen von den zu analysierenden Optionen und den erlaubten Kurzoptionen
  • Die Parameter, das sind die Optionen, die Sie dem Programm übergeben haben. Die Optionen, die Sie analysieren und deren tatsächliche Werte festlegen möchten.

Beispiele

getopt -l "name:,version::,verbose" -a -o "n:v::V" -- -name=Karthik -version=5.2 -verbose

GETOPT_OPTIONEN

getopt_optionen ändern die Art und Weise, wie Befehlszeilenparameter analysiert werden.

Hier sind einige der getopt_optionen

Option: -l oder --longoptions

Bedeutet, dass der getopt-Befehl mehrzeichen Optionen erkennen sollte. Mehrere Optionen werden durch Kommas getrennt.

Zum Beispiel wird --name=Karthik als Langoption in der Befehlszeile gesendet. In getopt werden Langoptionen wie folgt verwendet

getopt -l "name:,version" -- "" --name=Karthik

Da name: angegeben ist, sollte die Option einen Wert enthalten

Option: -a oder --alternative

Bedeutet, dass der getopt-Befehl erlauben soll, dass eine Langoption einen einzelnen Bindestrich '-' anstelle von doppeltem Bindestrich '--' hat.

Beispielweise, anstelle von --name=Karthik könnte man einfach -name=Karthik verwenden

getopt -a -l "name:,version" -- "" -name=Karthik

Ein vollständiges Skriptbeispiel mit dem Code:

#!/bin/bash

# Dateiname: commandLine.sh
# Autor: @theBuzzyCoder

showHelp() {
# `cat << EOF` bedeutet, dass cat aufhören soll zu lesen, wenn EOF erkannt wird
cat << EOF  
Verwendung: ./installer -v  [-hrV]
Installieren von Vorbedingungen für EspoCRM mit Docker im Entwicklungsmodus

-h, -help,          --help                  Hilfe anzeigen

-v, -espo-version,  --espo-version          Bestimmte Version von EspoCRM festlegen und herunterladen

-r, -rebuild,       --rebuild               PHP-Vendordatei mit Composer neu erstellen und kompiliertes CSS mit Grunt kompilieren

-V, -verbose,       --verbose               Skript im Verbose-Modus ausführen. Jeden Schritt der Ausführung ausgeben.

EOF
# EOF wurde oben gefunden und daher stoppt der cat-Befehl das Lesen. Dies ist äquivalent zu echo, aber viel ordentlicher beim Ausdrucken.
}

export version=0
export verbose=0
export rebuilt=0

# $@ sind alle an das Skript übergebenen Befehlszeilenparameter.
# -o ist für Kurzoptionen wie -v
# -l ist für Langoptionen mit doppeltem Bindestrich wie --version
# das Komma trennt verschiedene Langoptionen
# -a ist für Langoptionen mit einem Bindestrich wie -version
options=$(getopt -l "help,version:,verbose,rebuild,dryrun" -o "hv:Vrd" -a -- "$@")

# set --:
# Wenn diesem Optionszeichen keine Argumente folgen, werden die positionellen Parameter verworfen. Andernfalls wird den positionellen Parametern
# die Argumente zugewiesen, auch wenn einige von ihnen mit einem „-“ beginnen.
eval set -- "$options"

while true
do
case "$1" in
-h|--help) 
    showHelp
    exit 0
    ;;
-v|--version) 
    shift
    export version="$1"
    ;;
-V|--verbose)
    export verbose=1
    set -xv  # Set xtrace und Verbose-Modus.
    ;;
-r|--rebuild)
    export rebuild=1
    ;;
--)
    shift
    break;;
esac
shift
done

Ausführen dieser Skriptdatei:

# Mit zusammengefassten Kurzoptionen und Langoption
# Mit doppeltem Bindestrich '--version'

bash commandLine.sh --version=1.0 -rV
# Mit zusammengefassten Kurzoptionen und Langoption
# Mit einem Bindestrich '-version'

bash commandLine.sh -version=1.0 -rV

# ODER mit Kurzoption, die einen Wert hat, Wert durch Leerzeichen getrennt
# nach Schlüssel

bash commandLine.sh -v 1.0 -rV

# ODER mit Kurzoption, die einen Wert hat, Wert ohne Leerzeichen
# Trennung vom Schlüssel.

bash commandLine.sh -v1.0 -rV

# ODER Individuelle Kurzoptionen trennen

bash commandLine.sh -v1.0 -r -V

48voto

Brian Cain Punkte 13956

Das Beispiel, das mit getopt geliefert wird (mein Distro hat es in /usr/share/getopt/getopt-parse.bash platziert), scheint alle deine Fälle abzudecken:

#!/bin/bash

# Ein kleines Beispielprogramm zur Verwendung des neuen getopt(1)-Programms.
# Dieses Programm funktioniert nur mit bash(1)
# Ein ähnliches Programm, das die tcsh(1)-Sriptsprache verwendet, findet man
# als parse.tcsh

# Beispiel Eingabe und Ausgabe (vom bash-Prompt):
# ./parse.bash -a par1 'another arg' --c-long 'wow!*\?' -cmore -b " very long "
# Option a
# Option c, kein Argument
# Option c, Argument 'more'
# Option b, Argument ' very long '
# Verbleibende Argumente:
# --> 'par1'
# --> 'another arg'
# --> 'wow!*\?'

# Beachten Sie, dass wir `"$@"' verwenden, damit jeder Befehlszeilenparameter zu einem
# separaten Wort expandiert. Die Anführungszeichen um '$@' sind unerlässlich!
# Wir benötigen TEMP, da der `eval set --' den Rückgabewert von getopt löschen würde.
TEMP=$(getopt -o ab:c:: --long a-long,b-long:,c-long:: \
              -n 'example.bash' -- "$@")

if [ $? != 0 ] ; then echo "Beende..." >&2 ; exit 1 ; fi

# Beachten Sie die Anführungszeichen um '$TEMP': Sie sind unerlässlich!
eval set -- "$TEMP"

while true ; do
    case "$1" in
        -a|--a-long) echo "Option a" ; shift ;;
        -b|--b-long) echo "Option b, Argument '$2'" ; shift 2 ;;
        -c|--c-long) 
            # c hat ein optionales Argument. Da wir im zitierten Modus sind,
            # wird ein leerer Parameter generiert, falls sein optionales
            # Argument nicht gefunden wird.
            case "$2" in
                "") echo "Option c, kein Argument"; shift 2 ;;
                *)  echo "Option c, Argument '$2'" ; shift 2 ;;
            esac ;;
        --) shift ; break ;;
        *) echo "Interner Fehler!" ; exit 1 ;;
    esac
done
echo "Verbleibende Argumente:"
for arg do echo '--> '"'$arg'" ; done

14voto

POSIX 7 Beispiel

Es lohnt sich auch, das Beispiel aus dem Standard zu überprüfen: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html

aflag=
bflag=
while getopts ab: name
do
    case $name in
    a)    aflag=1;;
    b)    bflag=1
          bval="$OPTARG";;
    ?)   printf "Verwendung: %s: [-a] [-b Wert] args\n" $0
          exit 2;;
    esac
done
if [ ! -z "$aflag" ]; then
    printf "Option -a angegeben\n"
fi
if [ ! -z "$bflag" ]; then
    printf 'Option -b "%s" angegeben\n' "$bval"
fi
shift $(($OPTIND - 1))
printf "Die verbleibenden Argumente sind: %s\n" "$*"

Und dann können wir es ausprobieren:

$ sh a.sh
Die verbleibenden Argumente sind: 
$ sh a.sh -a
Option -a angegeben
Die verbleibenden Argumente sind: 
$ sh a.sh -b
Kein Argument für die Option -b
Verwendung: a.sh: [-a] [-b Wert] args
$ sh a.sh -b myval
Option -b "myval" angegeben
Die verbleibenden Argumente sind: 
$ sh a.sh -a -b myval
Option -a angegeben
Option -b "myval" angegeben
Die verbleibenden Argumente sind: 
$ sh a.sh remain
Die verbleibenden Argumente sind: remain
$ sh a.sh -- -a remain
Die verbleibenden Argumente sind: -a remain

Getestet unter Ubuntu 17.10, sh ist dash 0.5.8.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X