2542 Stimmen

Wie analysiere ich Kommandozeilenargumente in der Bash?

Angenommen, ich habe ein Skript, das mit dieser Zeile aufgerufen wird:

./myscript -vfd ./foo/bar/someFile -o /fizz/someOtherFile

oder dieses:

./myscript -v -f -d -o /fizz/someOtherFile ./foo/bar/someFile 

Wie kann man dies so interpretieren, dass in jedem Fall (oder einer Kombination von beiden) $v , $f y $d werden alle auf true y $outFile wird gleich sein mit /fizz/someOtherFile ?

1 Stimmen

Für zsh-Benutzer gibt es ein großartiges builtin namens zparseopts, das das kann: zparseopts -D -E -M -- d=debug -debug=d Und haben beide -d y --debug im $debug Array echo $+debug[1] gibt 0 oder 1 zurück, wenn einer dieser Werte verwendet wird. Ref: zsh.org/mla/users/2011/msg00350.html

2 Stimmen

Ein wirklich gutes Tutorial: linuxcommand.org/lc3_wss0120.php . Besonders gut gefällt mir das Beispiel "Befehlszeilenoptionen".

0 Stimmen

Ich habe ein Skript erstellt, das dies für Sie erledigt, es heißt - github.com/unfor19/bargs

2voto

Verwenden Sie das Modul "Argumente" von bash-modules

Exemple :

#!/bin/bash
. import.sh log arguments

NAME="world"

parse_arguments "-n|--name)NAME;S" -- "$@" || {
  error "Cannot parse command line."
  exit 1
}

info "Hello, $NAME!"

2voto

Meir Gabay Punkte 2062

Ich habe ein Skript geschrieben, das das Parsen von Kommandozeilenargumenten erleichtert - https://github.com/unfor19/bargs

Beispiele

$ bash example.sh -n Willy --gender male -a 99
Name:      Willy
Age:       99
Gender:    male
Location:  chocolate-factory

$ bash example.sh -n Meir --gender male
[ERROR] Required argument: age

Usage: bash example.sh -n Willy --gender male -a 99

--person_name  |  -n  [Willy]              What is your name?
--age          |  -a  [Required]
--gender       |  -g  [Required]
--location     |  -l  [chocolate-factory]  insert your location

$ bash example.sh -h

Usage: bash example.sh -n Willy --gender male -a 99
--person_name  |  -n  [Willy]              What is your name?
--age          |  -a  [Required]
--gender       |  -g  [Required]
--location     |  -l  [chocolate-factory]  insert your location

2voto

Top-Master Punkte 5094

Am Ende habe ich die dash (oder /bin/sh ) Version des akzeptierte Antwort grundsätzlich ohne Array-Verwendung:

while [[ $# -gt 0 ]]; do
    case "$1" in
    -v|--verbose) verbose=1; shift;;
    -o|--output) if [[ $# -gt 1 && "$2" != -* ]]; then
            file=$2; shift 2
        else
            echo "-o requires file-path" 1>&2; exit 1
        fi ;;
    --)
        while [[ $# -gt 0 ]]; do BACKUP="$BACKUP;$1"; shift; done
        break;;
    *)
        BACKUP="$BACKUP;$1"
        shift
        ;;
    esac
done
# Restore unused arguments.
while [ -n "$BACKUP" ] ; do
    [ ! -z "${BACKUP%%;*}" ] && set -- "$@" "${BACKUP%%;*}"
    [ "$BACKUP" = "${BACKUP/;/}" ] && break
    BACKUP="${BACKUP#*;}"
done

1voto

Masadow Punkte 745

Hier ist meine verbesserte Lösung von Bruno Bronoskys Antwort unter Verwendung von variablen Arrays.

Sie können die Position der Parameter mischen und erhalten ein Parameter-Array, das die Reihenfolge ohne die Optionen beibehält

#!/bin/bash

echo $@

PARAMS=()
SOFT=0
SKIP=()
for i in "$@"
do
case $i in
    -n=*|--skip=*)
    SKIP+=("${i#*=}")
    ;;
    -s|--soft)
    SOFT=1
    ;;
    *)
        # unknown option
        PARAMS+=("$i")
    ;;
esac
done
echo "SKIP            = ${SKIP[@]}"
echo "SOFT            = $SOFT"
    echo "Parameters:"
    echo ${PARAMS[@]}

Wird zum Beispiel ausgegeben:

$ ./test.sh parameter -s somefile --skip=.c --skip=.obj
parameter -s somefile --skip=.c --skip=.obj
SKIP            = .c .obj
SOFT            = 1
Parameters:
parameter somefile

0 Stimmen

Sie verwenden Shift für die bekannten Argumente und nicht für die unbekannten, so dass Ihre verbleibenden $@ alle Argumente bis auf die ersten beiden (in der Reihenfolge ihrer Übergabe), was zu einigen Fehlern führen kann, wenn Sie versuchen, mit $@ später. Sie brauchen die Verschiebung für die =-Parameter nicht, da Sie keine Leerzeichen behandeln und den Wert mit der Teilstring-Entfernung erhalten #*=

0 Stimmen

Sie haben Recht, da ich eine PARAMS-Variable erstellt habe, brauche ich Shift überhaupt nicht zu verwenden.

1voto

terijo001 Punkte 48

Einfach und leicht zu ändern, Parameter können in beliebiger Reihenfolge angegeben werden. Dies kann geändert werden, um Parameter in beliebiger Form (-a, --a, a, usw.) zu übernehmen.

for arg in "$@"
do
   key=$(echo $arg | cut -f1 -d=)`
   value=$(echo $arg | cut -f2 -d=)`
   case "$key" in
        name|-name)      read_name=$value;;
        id|-id)          read_id=$value;;
        *)               echo "I dont know what to do with this"
   ease
done

0 Stimmen

In diesem Skript, ease ist falsch und sollte ersetzt werden durch esac um den Fallblock zu schließen

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