Parsa flaggor och argument med getopts
Implementera professionella kommandoradsgränssnitt med getopts för korta alternativ, obligatoriska argument och användningsmeddelanden.
Parsa flaggor och argument med getopts är en gratis lektion i DevOps-bootcamp på CoddyKit. Detta är lektion 3 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för DevOps-bootcamp, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i DevOps-bootcamp innehåller totalt 4 lektioner.
Varför getopts finns
Alla verkliga skript behöver förr eller senare ta emot flaggor som -v, -o output.txt eller -n 5. Att tolka dessa manuellt med $1, $2… blir snabbt skört.
getopts är det inbyggda verktyget enligt POSIX-standarden som hanterar korta flaggor (-a, -b) på ett tillförlitligt sätt, även flaggor som tar ett argument. Det är inbyggt i alla POSIX-skal, så inga beroenden krävs.
- Hanterar kombinerade flaggor:
-vn 5=-v -n 5 - Rapporterar okända flaggor på ett kontrollerat sätt
- Anger automatiskt standardvariablerna
OPTINDochOPTARG
I den här lektionen bygger ni ett komplett, professionellt CLI-gränssnitt med getopts från grunden.
Syntaxen för getopts
Grundsyntaxen är en while-loop som anropar getopts vid varje iteration:
while getopts "optstring" varname; do
case "$varname" in
...
esac
done- optstring — en sträng som listar varje accepterad flaggbokstav. Ett kolon efter en bokstav betyder att flaggan kräver ett argument.
- varname — tar emot den aktuella flaggbokstaven vid varje iteration.
- OPTARG — sätts automatiskt till argumentets värde när ett kolon följer efter bokstaven.
- OPTIND — indexet för nästa argument som ska behandlas; använd
shift $((OPTIND - 1))efter loopen för att göra återstående positionsparametrar tillgängliga.
#!/usr/bin/env bash
# Minimal skeleton — shows the loop structure
while getopts 'vn:' opt; do
case "$opt" in
v) echo "Verbose mode on" ;;
n) echo "Count = $OPTARG" ;;
?) echo "Unknown option: -$OPTARG" >&2; exit 1 ;;
esac
doneDefiniera en optstring
optstring är en kompakt deklaration av CLI-gränssnittets kontrakt. Varje tecken representerar en accepterad flagga.
'abc'— accepterar-a,-b,-c(inga argument)'a:bc'—-akräver ett argument;-boch-cgör det inte':abc'— ett inledande kolon aktiverar tyst felläge (skriptet hanterar felaktiga flaggor i stället för att skalet skriver ut ett meddelande)
Tyst läge rekommenderas i produktionsskript eftersom det ger full kontroll över felmeddelanden och avslutningskoder.
#!/usr/bin/env bash
# optstring ':o:vq'
# -o requires an argument (output file)
# -v verbose flag (no argument)
# -q quiet flag (no argument)
# Leading ':' = silent error mode
while getopts ':o:vq' opt; do
case "$opt" in
o) OUTPUT="$OPTARG" ;;
v) VERBOSE=1 ;;
q) QUIET=1 ;;
:) echo "Error: -$OPTARG requires an argument" >&2; exit 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; exit 1 ;;
esac
done
echo "OUTPUT=$OUTPUT VERBOSE=$VERBOSE QUIET=$QUIET"OPTARG och obligatoriska argument
När en flagga följs av ett kolon i optstring lagrar getopts dess värde i OPTARG. Användaren kan skriva argumentet antingen med eller utan mellanslag:
-o report.txt-oreport.txt
Båda formerna tolkas identiskt. Det här är en av de viktigaste fördelarna jämfört med manuell tolkning med $1/shift.
I tyst läge (ett inledande ':' i optstring) gör ett saknat argument att getopts sätter varname till : och OPTARG till flaggbokstaven — perfekt för ett riktat felmeddelande.
#!/usr/bin/env bash
# Demonstrate OPTARG with a file-processing script
while getopts ':i:o:' opt; do
case "$opt" in
i) INPUT="$OPTARG" ;;
o) OUTPUT="$OPTARG" ;;
:) echo "Error: option -$OPTARG needs a value" >&2; exit 1 ;;
\?) echo "Error: unknown flag -$OPTARG" >&2; exit 1 ;;
esac
done
echo "Input : ${INPUT:-<not set>}"
echo "Output : ${OUTPUT:-<not set>}"Skifta förbi flaggor med OPTIND
När getopts är klar innehåller OPTIND indexet för det första argumentet som inte är en flagga. Använd shift för att ta bort alla behandlade flaggor, så att $1, $2… refererar till de återstående positionsparametrarna (till exempel filnamn).
Idiomets form är alltid:
shift $((OPTIND - 1))Efter skiftningen innehåller $@ endast de argument som inte var flaggor — kommandots operander.
#!/usr/bin/env bash
# Shows OPTIND shift and leftover positional args
VERBOSE=0
while getopts ':vn:' opt; do
case "$opt" in
v) VERBOSE=1 ;;
n) COUNT="$OPTARG" ;;
:) echo "Error: -$OPTARG requires an argument" >&2; exit 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1))
echo "VERBOSE=$VERBOSE COUNT=${COUNT:-1}"
echo "Remaining args: $*"Skriv en usage-funktion
Ett professionellt skript har alltid en usage()-funktion som skriver ut ett hjälpmeddelande och avslutar. Konventionen är:
- Skriv till stderr (fd 2) så att meddelandet inte blandas in i rörlagrade utdata
- Avsluta med koden 0 för
-h/--helpoch med koden 1 vid ogiltig användning - Anropa
usage 1vid fel ochusage 0från hanteraren för-h
#!/usr/bin/env bash
usage() {
cat >&2 <<EOF
Usage: $(basename "$0") [-v] [-n COUNT] [-o FILE] [FILE...]
Options:
-v Verbose output
-n COUNT Repeat COUNT times (default: 1)
-o FILE Write output to FILE
-h Show this help
EOF
exit "${1:-0}"
}
while getopts ':vn:o:h' opt; do
case "$opt" in
v) VERBOSE=1 ;;
n) COUNT="$OPTARG" ;;
o) OUTFILE="$OPTARG" ;;
h) usage 0 ;;
:) echo "Error: -$OPTARG requires a value" >&2; usage 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; usage 1 ;;
esac
done
shift $((OPTIND - 1))
echo "Parsed OK — verbose=${VERBOSE:-0} count=${COUNT:-1} out=${OUTFILE:--}"Standardvärden och validering
Validera och ange standardvärden efter tolkningen, innan något verkligt arbete utförs. Håll tolkningsfasen (loopen) åtskild från logikfasen. Då blir båda delarna lättare att läsa och testa.
- Använd
${VAR:-default}för standardvärden inline - Validera numeriska argument med ett reguljärt uttryck eller en aritmetisk kontroll
- Kontrollera att obligatoriska flaggor faktiskt angavs
#!/usr/bin/env bash
usage() { echo "Usage: $(basename "$0") -n COUNT [-v]" >&2; exit 1; }
VERBOSE=0
COUNT=''
while getopts ':n:v' opt; do
case "$opt" in
n) COUNT="$OPTARG" ;;
v) VERBOSE=1 ;;
:) echo "Error: -$OPTARG needs a value" >&2; usage ;;
\?) echo "Error: -$OPTARG unknown" >&2; usage ;;
esac
done
shift $((OPTIND - 1))
# Validation phase
[[ -z "$COUNT" ]] && { echo "Error: -n COUNT is required" >&2; usage; }
[[ "$COUNT" =~ ^[0-9]+$ ]] || { echo "Error: COUNT must be a positive integer" >&2; usage; }
for (( i=1; i<=COUNT; i++ )); do
[[ $VERBOSE -eq 1 ]] && echo "Iteration $i of $COUNT"
echo "Hello, world!"
doneKombinera flaggor på kommandoraden
getopts hanterar automatiskt kombinerade korta flaggor som skrivs utan mellanslag, vilket är standardkonventionen i Unix:
-v -qmotsvarar-vq-n 5 -vmotsvarar-n5 -veller-vn5
Ni behöver inte skriva någon extra kod för att stödja detta — getopts itererar automatiskt genom varje tecken i en kombinerad flaggsträng. Det här är ytterligare ett viktigt skäl att använda getopts i stället för manuell tolkning.
#!/usr/bin/env bash
# Test combined flag parsing
# Run as: bash script.sh -vq -n3
VERBOSE=0; QUIET=0; COUNT=1
while getopts ':vqn:' opt; do
case "$opt" in
v) VERBOSE=1 ;;
q) QUIET=1 ;;
n) COUNT="$OPTARG" ;;
:) echo "Error: -$OPTARG needs value" >&2; exit 1 ;;
\?) echo "Error: unknown -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1))
echo "verbose=$VERBOSE quiet=$QUIET count=$COUNT"Hantera avgränsaren med dubbla bindestreck
Unix-kommandon accepterar -- (dubbla bindestreck) som en uttrycklig signal om att flaggtolkningen ska stoppas. Allt efter -- behandlas som ett positionsargument, även om det ser ut som en flagga.
getopts stannar automatiskt när det stöter på --. Efter shift $((OPTIND - 1)) är de dubbla bindestrecken borta och $@ innehåller endast operanderna.
Detta är viktigt för skript som arbetar med filnamn som kan börja med ett bindestreck, till exempel:
myscript.sh -v -- -strangefile.txt#!/usr/bin/env bash
# Demonstrate -- separator
# Run as: bash script.sh -v -- file1.txt -oddname.txt
VERBOSE=0
while getopts ':v' opt; do
case "$opt" in
v) VERBOSE=1 ;;
\?) echo "Unknown option -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1)) # removes -v and the '--' separator
echo "Verbose: $VERBOSE"
echo "Files to process:"
for f in "$@"; do
echo " -> $f"
doneOmslut getopts i en biblioteksfunktion
I modulära skript kan ni kapsla in getopts i en parse_args()-funktion som anger globala variabler (eller namngivningsreferenser). Då hålls main() ren och tolkningsfunktionen kan läsas in från andra skript.
Viktiga regler för det här mönstret:
- Deklarera flaggvariablerna innan funktionen anropas
- Använd
global-variabler eller skicka värden via namngivningsreferenser (declare -n) - Returnera en avslutningskod som inte är noll vid felaktig indata, så att
mainkan reagera
#!/usr/bin/env bash
# Global option variables
VERBOSE=0; OUTPUT=''; COUNT=1
parse_args() {
local opt
while getopts ':vn:o:h' opt; do
case "$opt" in
v) VERBOSE=1 ;;
n) COUNT="$OPTARG" ;;
o) OUTPUT="$OPTARG" ;;
h) echo "Usage: $(basename "$0") [-v] [-n N] [-o FILE]"; exit 0 ;;
:) echo "Error: -$OPTARG needs a value" >&2; return 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; return 1 ;;
esac
done
shift $((OPTIND - 1))
ARGS=("$@") # leftover positional args stored in array
}
main() {
parse_args "$@" || exit 1
echo "verbose=$VERBOSE count=$COUNT output=${OUTPUT:--} args=${ARGS[*]}"
}
main "$@"Ett komplett verkligt exempel: en loggarkiverare
Här är ett komplett, verklighetsnära skript som använder allt som behandlats i den här lektionen: optstring med obligatoriska argument, tyst felläge, en usage-funktion, standardvärden, validering och OPTIND-skiftning.
Studera strukturen — den är mallen ni bör följa i varje skript ni skriver som behöver ett CLI-gränssnitt.
#!/usr/bin/env bash
# archive_logs.sh — compress and move logs older than N days
set -euo pipefail
DESTDIR='/tmp/log_archive'
DAYS=30
VERBOSE=0
usage() {
cat >&2 <<EOF
Usage: $(basename "$0") [-v] [-d DAYS] [-o DIR] SOURCE_DIR
-d DAYS Archive logs older than DAYS (default: 30)
-o DIR Destination directory (default: /tmp/log_archive)
-v Verbose output
-h Show this help
EOF
exit "${1:-0}"
}
while getopts ':d:o:vh' opt; do
case "$opt" in
d) DAYS="$OPTARG" ;;
o) DESTDIR="$OPTARG" ;;
v) VERBOSE=1 ;;
h) usage 0 ;;
:) echo "Error: -$OPTARG requires a value" >&2; usage 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; usage 1 ;;
esac
done
shift $((OPTIND - 1))
# Validation
[[ $# -lt 1 ]] && { echo "Error: SOURCE_DIR is required" >&2; usage 1; }
[[ "$DAYS" =~ ^[0-9]+$ ]] || { echo "Error: DAYS must be numeric" >&2; exit 1; }
SOURCE="$1"
[[ -d "$SOURCE" ]] || { echo "Error: '$SOURCE' is not a directory" >&2; exit 1; }
mkdir -p "$DESTDIR"
[[ $VERBOSE -eq 1 ]] && echo "Archiving logs older than $DAYS days from $SOURCE to $DESTDIR"
find "$SOURCE" -name '*.log' -mtime "+$DAYS" -print | while read -r f; do
gzip -c "$f" > "$DESTDIR/$(basename "$f").gz"
[[ $VERBOSE -eq 1 ]] && echo " archived: $f"
done
echo "Done."Snabbkontroll: getopts optstring
Läs följande getopts-anrop och välj den korrekta beskrivningen av dess beteende:
while getopts ':f:vq' opt; doLektionssammanfattning: behärska getopts
Ni har lärt er att bygga professionella kommandoradsgränssnitt i Bash med getopts. Här är en sammanfattning av de viktigaste punkterna:
- Optstring-syntax — bokstäver utan kolon är booleska flaggor; ett kolon efter en bokstav betyder att den kräver ett argument; ett inledande kolon aktiverar tyst felläge.
- OPTARG — innehåller automatiskt argumentets värde för flaggor som kräver ett argument.
- OPTIND — använd
shift $((OPTIND - 1))efter loopen för att göra återstående positionsparametrar tillgängliga i$@. - Tyst felläge — rekommenderas i produktion; hantera själv fallen
:(saknat argument) och\?(okänd flagga) för full kontroll. - usage()-funktion — skriv alltid en sådan; skriv till stderr, avsluta med 0 för
-hoch med 1 vid fel. - Kombinerade flaggor — getopts hanterar automatiskt
-vqoch-n5utan extra kod. - Modulärt mönster — kapsla in getopts i en
parse_args()-funktion för rena, återanvändbara skript.
När ni behärskar getopts kan ni förvandla era skript från verktyg för ett enda ändamål till tillförlitliga och användarvänliga CLI-program som följer Unix-konventionerna.
Lär dig DevOps-bootcamp med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 142
- Lektioner
- 568
Vanliga frågor
Är lektionen ”Parsa flaggor och argument med getopts” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen DevOps-bootcamp, inklusive ”Parsa flaggor och argument med getopts”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i DevOps-bootcamp innehåller totalt 4 lektioner.
Vad lär jag mig i ”Parsa flaggor och argument med getopts”?
Implementera professionella kommandoradsgränssnitt med getopts för korta alternativ, obligatoriska argument och användningsmeddelanden. Ni övar på DevOps-bootcamp med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig DevOps-bootcamp?
Du behöver inga förkunskaper. Utbildningen i DevOps-bootcamp på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.
Hur lång tid tar lektionen ”Parsa flaggor och argument med getopts”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här DevOps-bootcamp-lektionen?
Ja. Varje DevOps-bootcamp-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Utforma funktioner med lokal omfattning och returkoder
- Bygga och läsa in återanvändbara Bash-bibliotek
- Parsa flaggor och argument med getopts
- Skicka arrayer och associativa mappar mellan funktioner