Controleer het aantal argumenten dat aan een Bash-script is doorgegeven

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 testspaties 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 -gedoor 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, whileen 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 -1als de geretourneerde waarde, dus Ik kan het net zo goed goed doen.

-1hoewel geaccepteerd door Bash als argument om exitis niet expliciet gedocumenteerd en is niet juist om als algemene suggestie te worden gebruikt. 64is ook de meest formele waarde omdat deze is gedefinieerd in sysexits.hmet #define EX_USAGE 64 /* command line usage error */. De meeste tools zoals lsretourneren ook 2bij ongeldige argumenten. Ik gaf ook altijd 2terug in mijn scripts, maar de laatste tijd kon het me niet meer schelen, en gebruikte ik gewoon 1in alle fouten. Maar laten we gewoon 2hier 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


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

>&2wordt 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:

  1. test de bash-variabele voor de grootte van parameters $# is niet gelijk aan 1 (ons aantal subcommando’s)
  2. indien waar, roep dan de functie gebruik() aan en sluit af met status 1
  3. 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.

Other episodes