Bash Getopts - ein bestimmtes Flag vor allen anderen parsen

Arvyr

Cadet 4th Year
Registriert
Sep. 2018
Beiträge
74
Hallo,

ich spiele derzeit mit einem kleinen Skript zum erstellen einer zweistufigen Linux-CA rum.
Ich möchte das Skript gerne mit Argumenten steuern und habe dafür mit getopts bereits ein Grundgerüst erstellt.
An einer Sache scheitere ich bisher und konnte noch keine Lösung finden.

Ich möchte, dass der Switchparameter -e vor allen anderen erkannt wird und dann den Wert für die Variable key auf "ec" setzt.
Erst danach sollen andere Flags wie für die Root oder SubCA erkannt werden und die jeweilige Funktion starten.
Würde ich aktuell das Skript mit Flags in der Reihenfolge skript.sh -r -e starten, würde erst die RootCA mit Defaultwerten installiert und anschließend der Wert für key gesetzt, wenns zu spät ist.
Wie setzt man dieses am besten um?

Hier mal mein getopts-Abschnitt:

Bash:
#!/bin/bash
# Getopts-Test

print_usage() {
    echo "Usage: ..."
}

# Helfervariablen um Flags nur einmal zu parsen
rdone=0
idone=0
wdone=0
odone=0
mdone=0
tdone=0
edone=0

key="rsa"

while getopts 'riwom:t:u:e' flag; do
    case "${flag}" in
        e)    key="ec" ;;
        r)    if [ $rdone == 0 ]; then
                echo "rootca"
                echo "with ${key}"
                rdone=1
            fi ;;
        i)    echo "subca" ;;
        w)    echo "web" ;;
        o)    echo "ocsp" ;;
        m)    echo "move"; echo "${OPTARG}" ;;
        u)    echo "user"; echo "${OPTARG}" ;;
        t)    if [ $tdone == 0 ]; then
                echo "IP: ${OPTARG}"
                tdone=1
            fi ;; 
        *)    print_usage
            exit 0 ;;
    esac
done
shift $((OPTIND-1))

Zusatz:
Bei PowerShell gibt es Parametersets bei denen man abhängig von einem gesetzten Parameter andere fordern kann.
Gibt es das für Bash auch?
In meinem Beispiel benötigte ich das u-Flag für einen User nur dann, wenn das m-Flag für Move gesetzt ist.
Ansonsten kann dieses Flag ignoriert werden.
 
Ja, dafür ist getopts nicht gemacht, es ist gedacht um alle Optionen einzulesen und verschiedene Dinge zu tun, die dann von der restlichen Logik verwendet werden.
In diesem Fall wird aber die Logik in das getopts verschoben, was nicht Sinn der Sache ist.
Du könntest davor noch ein kurzes getotps ausführen, was sich nur darum kümmert.
Ja ist unschön, aber so ist es nun mal:

Bash:
#!/bin/bash
# Getopts-Test

print_usage() {
    echo "Usage: ..."
}

# Helfervariablen um Flags nur einmal zu parsen
rdone=0
idone=0
wdone=0
odone=0
mdone=0
tdone=0
edone=0

key="rsa"

while getopts 'riwom:t:u:e' flag1; do
  case "${flag1}" in
    e)  key="ec" ;;
  esac
done

while getopts 'riwom:t:u:e' flag2; do
    case "${flag2}" in
        e)    key="ec" ;;
        r)    if [ $rdone == 0 ]; then
                echo "rootca"
                echo "with ${key}"
                rdone=1
            fi ;;
        i)    echo "subca" ;;
        w)    echo "web" ;;
        o)    echo "ocsp" ;;
        m)    echo "move"; echo "${OPTARG}" ;;
        u)    echo "user"; echo "${OPTARG}" ;;
        t)    if [ $tdone == 0 ]; then
                echo "IP: ${OPTARG}"
                tdone=1
            fi ;;
        *)    print_usage
            exit 0 ;;
    esac
done
shift $((OPTIND-1))
 
  • Gefällt mir
Reaktionen: Arvyr
Ich habe noch etwas getestet und bin quasi zu einem sehr ähnlichen Ergebnis gekommen:

Bash:
for arg in "$@"
do
    case $arg in
        -e)    key="ec" ;;
    esac
done

while getopts 'riwom:t:u:e' flag; do
    case "${flag}" in
        r)    if [ $rdone == 0 ]; then
                echo "rootca"
                echo "with ${key}"
                rdone=1
            fi ;;
        i)    echo "subca" ;;
        w)    echo "web" ;;
        o)    echo "ocsp" ;;
        m)    echo "move"; echo "${OPTARG}" ;;
        u)    echo "user"; echo "${OPTARG}" ;;
        t)    if [ $tdone == 0 ]; then
                echo "IP: ${OPTARG}"
                tdone=1
            fi ;;
        e)    ;;
        *)    print_usage
            exit 0 ;;
    esac
done

Nun funktioniert das so wie ich möchte.
Aber danke für deine Lösung.

Bleibt ja im Grunde nur noch das ganze mit Parametersets zu erweitern sofern das möglich ist.
 
  • Gefällt mir
Reaktionen: GTrash81 und Hayda Ministral
Zurück
Oben