Ik wil dat mijn Bash-script een foutmelding afdrukt als niet aan het vereiste aantal argumenten wordt voldaan.
Ik heb de volgende code geprobeerd:
#!/bin/bash
echo Script name: $0
echo $# arguments
if [$# -ne 1];
then echo "illegal number of parameters"
fi
Om een onbekende reden krijg ik de volgende foutmelding:
test: line 4: [2: command not found
Wat doe ik verkeerd?
Antwoord 1, autoriteit 100%
Net als elk ander eenvoudig commando, vereist [ ... ]
of test
spaties tussen de argumenten.
if [ "$#" -ne 1 ]; then
echo "Illegal number of parameters"
fi
Of
if test "$#" -ne 1; then
echo "Illegal number of parameters"
fi
Suggesties
Als je in Bash bent, gebruik dan liever [[ ]]
omdat het geen woordsplitsing en padnaamuitbreiding voor de variabelen doet, zodat citeren misschien niet nodig is, tenzij het deel uitmaakt van een uitdrukking.
p>
[[ $# -ne 1 ]]
Het heeft ook enkele andere functies, zoals niet-aangehaalde voorwaardegroepering, patroonovereenkomst (uitgebreide patroonovereenkomst met extglob
) en regex-overeenkomst.
Het volgende voorbeeld controleert of argumenten geldig zijn. Het staat een enkel argument of twee toe.
[[ ($# -eq 1 || ($# -eq 2 && $2 == <glob pattern>)) && $1 =~ <regex pattern> ]]
Voor pure rekenkundige uitdrukkingen is het voor sommigen misschien nog steeds beter om (( ))
te gebruiken, maar ze zijn nog steeds mogelijk in [[ ]]
met zijn rekenkundige operatoren zoals -eq
, -ne
, -lt
, -le
, -gt
, of -ge
door de uitdrukking als een enkel stringargument te plaatsen:
A=1
[[ 'A + 1' -eq 2 ]] && echo true ## Prints true.
Dat zou handig zijn als je het ook zou moeten combineren met andere functies van [[ ]]
.
Houd er rekening mee dat [[ ]]
en (( ))
trefwoorden zijn met hetzelfde ontledingsniveau als if
, case
, while
en for
.
Ook zoals Davesuggereerde, kunnen foutmeldingen beter naar stderr worden gestuurd, zodat ze niet worden opgenomen wanneer stdout wordt omgeleid :
echo "Illegal number of parameters" >&2
Het script afsluiten
Het is ook logisch om het script af te sluiten als er ongeldige parameters aan worden doorgegeven. Dit is al gesuggereerd in de opmerkingendoor ekangasmaar iemand heeft dit antwoord bewerkt om het te hebben met -1
als de geretourneerde waarde, dus Ik kan het net zo goed goed doen.
-1
hoewel geaccepteerd door Bash als argument om exit
is niet expliciet gedocumenteerd en is niet juist om als algemene suggestie te worden gebruikt. 64
is ook de meest formele waarde omdat deze is gedefinieerd in sysexits.h
met #define EX_USAGE 64 /* command line usage error */
. De meeste tools zoals ls
retourneren ook 2
bij ongeldige argumenten. Ik gaf ook altijd 2
terug in mijn scripts, maar de laatste tijd kon het me niet meer schelen, en gebruikte ik gewoon 1
in alle fouten. Maar laten we gewoon 2
hier plaatsen, aangezien dit het meest voorkomt en waarschijnlijk niet besturingssysteem-specifiek is.
if [[ $# -ne 1 ]]; then
echo "Illegal number of parameters"
exit 2
fi
Referenties
- Voorwaardelijke expressies bash
- Voorwaardelijke constructies
- Patroonovereenkomst
- Woorden splitsen
- Bestandsuitbreiding (vorige Padnaamuitbreiding)
- Eenvoudige commando’s
Antwoord 2, autoriteit 7%
Het kan een goed idee zijn om rekenkundige uitdrukkingente gebruiken als je te maken hebt met nummers.
if (( $# != 1 )); then
>&2 echo "Illegal number of parameters"
fi
>&2
wordt gebruikt om de foutmelding naar stderr te schrijven.
Antwoord 3, autoriteit 3%
Op []: !=, =, == … zijn stringvergelijkingsoperatoren en -eq, -gt … zijn rekenkundigebinaire.
Ik zou gebruiken:
if [ "$#" != "1" ]; then
Of:
if [ $# -eq 1 ]; then
Antwoord 4, autoriteit 3%
Als je alleen geïnteresseerd bent in bail-out als een bepaald argument ontbreekt, Parametervervangingis geweldig:
#!/bin/bash
# usage-message.sh
: ${1?"Usage: $0 ARGUMENT"}
# Script exits here if command-line parameter absent,
#+ with following error message.
# usage-message.sh: 1: Usage: usage-message.sh ARGUMENT
Antwoord 5
Een eenvoudige one-liner die werkt, kan worden gedaan met:
[ "$#" -ne 1 ] && ( usage && exit 1 ) || main
Dit komt neer op:
- test de bash-variabele voor de grootte van parameters $# is niet gelijk aan 1 (ons aantal subcommando’s)
- indien waar, roep dan de functie gebruik() aan en sluit af met status 1
- noem de main()-functie
Opmerkingen:
- usage() kan gewoon simpel zijn echo “$0: params”
- main kan één lang script zijn
Antwoord 6
Bekijk dezebash-cheatsheet, het kan veel helpen.
Om de lengte van de doorgegeven argumenten te controleren, gebruikt u "$#"
Om de array van doorgegeven argumenten te gebruiken, gebruik je "$@"
Een voorbeeld van het controleren van de lengte en iteratie zou zijn:
myFunc() {
if [[ "$#" -gt 0 ]]; then
for arg in "$@"; do
echo $arg
done
fi
}
myFunc "$@"
Dit artikel heeft me geholpen, maar miste een paar dingen voor mij en mijn situatie. Hopelijk helpt dit iemand.
Antwoord 7
Hier een simpele oneliner om te controleren of er maar één parameter wordt gegeven, anders verlaat u het script:
[ "$#" -ne 1 ] && echo "USAGE $0 <PARAMETER>" && exit
Antwoord 8
Als je aan de veilige kant wilt blijven, raad ik je aan getopts te gebruiken.
Hier is een klein voorbeeld:
while getopts "x:c" opt; do
case $opt in
c)
echo "-$opt was triggered, deploy to ci account" >&2
DEPLOY_CI_ACCT="true"
;;
x)
echo "-$opt was triggered, Parameter: $OPTARG" >&2
CMD_TO_EXEC=${OPTARG}
;;
\?)
echo "Invalid option: -$OPTARG" >&2
Usage
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
Usage
exit 1
;;
esac
done
bekijk hier meer details, bijvoorbeeld http://wiki.bash-hackers.org/howto /getopts_tutorial
Antwoord 9
Er is hier veel goede informatie, maar ik wilde een eenvoudig fragment toevoegen dat ik nuttig vind.
Hoe verschilt het van sommige hierboven?
- Drukt gebruik af naar stderr, wat beter is dan afdrukken naar stdout
- Retour met afsluitcode vermeld in dit andere antwoord
- Maakt geen one-liner…
_usage(){
_echoerr "Usage: $0 <args>"
}
_echoerr(){
echo "$*" >&2
}
if [ "$#" -eq 0 ]; then # NOTE: May need to customize this conditional
_usage
exit 2
fi
main "$@"
Antwoord 10
Je moet spaties toevoegen tussen de testconditie:
if [ $# -ne 1 ];
then echo "illegal number of parameters"
fi
Ik hoop dat dit helpt.