Sprawdź liczbę argumentów przekazywanych do skryptu Bash

Chciałbym, aby mój skrypt Bash wydrukował komunikat o błędzie, jeśli wymagany argument count nie jest spełniony.

Wypróbowałem następujący kod:

#!/bin/bash
echo Script name: $0
echo $# arguments 
if [$# -ne 1]; 
    then echo "illegal number of parameters"
fi

Z jakiegoś nieznanego powodu mam następujący błąd:

test: line 4: [2: command not found
Co robię źle?
Author: konsolebox, 2013-09-02

10 answers

Podobnie jak każde inne proste polecenie, [ ... ] lub test wymaga spacji między swoimi argumentami.

if [ "$#" -ne 1 ]; then
    echo "Illegal number of parameters"
fi

Lub

if test "$#" -ne 1; then
    echo "Illegal number of parameters"
fi

Sugestie

Gdy w Bash używasz zamiast tego [[ ]], ponieważ nie powoduje dzielenia wyrazów i rozszerzania nazwy ścieżki do zmiennych, które mogą nie być konieczne, chyba że są częścią wyrażenia.

[[ $# -ne 1 ]]

Posiada również inne funkcje, takie jak unquoted condition grouping, pattern matching (rozszerzone dopasowanie wzorca z extglob) i regex pasujące.

Poniższy przykład sprawdza, czy argumenty są poprawne. Pozwala na jeden lub dwa argumenty.

[[ ($# -eq 1 || ($# -eq 2 && $2 == <glob pattern>)) && $1 =~ <regex pattern> ]]

Dla czystych wyrażeń arytmetycznych, używanie (( )) dla niektórych może być jeszcze lepsze, ale nadal jest możliwe w [[ ]] z operatorami arytmetycznymi takimi jak -eq, -ne, -lt, -le, -gt, lub -ge poprzez umieszczenie wyrażenia jako pojedynczego argumentu łańcuchowego:

A=1
[[ 'A + 1' -eq 2 ]] && echo true  ## Prints true.

To powinno być pomocne, jeśli chcesz połączyć go z innymi cechami [[ ]] jako cóż.

Zwróć uwagę, że [[ ]] i (( )) są słowami kluczowymi, które mają taki sam poziom parsowania jak if, case, while, i for.

Również jak zasugerował Dave , komunikaty o błędach są lepiej wysyłane na stderr, aby nie były uwzględniane przy przekierowaniu stdout:

echo "Illegal number of parameters" >&2

Opuszczanie skryptu

Jest również logiczne, aby skrypt zakończył działanie, gdy zostaną mu przekazane nieprawidłowe parametry. Zostało to już zasugerowane w komentarzach przez ekangas ale ktoś edytował tę odpowiedź, aby mieć ją z -1 jako zwróconą wartością, więc równie dobrze mogę zrobić to dobrze.

-1 chociaż zaakceptowany przez Basha jako argument exit nie jest wyraźnie udokumentowany i nie może być używany jako powszechna sugestia. 64 jest również najbardziej formalną wartością, ponieważ jest zdefiniowana w sysexits.h przez #define EX_USAGE 64 /* command line usage error */. Większość narzędzi, takich jak ls, zwraca również 2 po nieprawidłowych argumentach. Ja również zwracałem 2 W moich skryptach, ale ostatnio już mi nie zależało i po prostu używałem 1 we wszystkich błędach. Ale po prostu umieśćmy 2 tutaj, ponieważ jest to najczęściej spotykane i prawdopodobnie nie specyficzne dla systemu operacyjnego.

if [[ $# -ne 1 ]]; then
    echo "Illegal number of parameters"
    exit 2
fi

Referencje

 1201
Author: konsolebox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-06 11:40:35

Dobrym pomysłem może być użycie wyrażeń arytmetycznych, jeśli mamy do czynienia z liczbami.

if (( $# != 1 )); then
    >&2 echo "Illegal number of parameters"
fi

>&2 służy do zapisu Komunikatu o błędzie na stderr.

 85
Author: Aleks-Daniel Jakimenko-A.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-05 09:09:57

On []:!=, =, == ... są operatorami porównania string oraz-eq, - gt ... są arytmetycznymi binarnymi.

Użyłbym:

if [ "$#" != "1" ]; then

Lub:

if [ $# -eq 1 ]; then
 42
Author: jhvaras,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-07 10:13:26

Jeśli interesuje Cię tylko brak konkretnego argumentu, substytucja parametru jest świetna:

#!/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
 35
Author: Pat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-16 05:32:45

Prosta jedna linijka, która działa można wykonać za pomocą:

[ "$#" -ne 1 ] && ( usage && exit 1 ) || main

To dzieli się na:

  1. przetestuj zmienną bash pod kątem wielkości parametrów $ # not equals 1 (nasza liczba poleceń podrzędnych)
  2. if true then call usage () function and exit with status 1
  3. else call main () function

}} Uwaga:

  • usage () może być po prostu prostym echo "$0: params "
  • main może być jednym długim skryptem
 14
Author: Dwight Spencer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-12 02:38:15

Sprawdź Ten Arkusz cheatowy bash, może bardzo pomóc.

Aby sprawdzić długość przekazywanych argumentów, należy użyć "$#"

Aby użyć tablicy przekazywanych argumentów, należy użyć "$@"

Przykład sprawdzania długości i iteracji to:

myFunc() {
  if [[ "$#" -gt 0 ]]; then
    for arg in "$@"; do
      echo $arg
    done
  fi
}

myFunc "$@"
Ten artykuł mi pomógł, ale brakowało mi kilku rzeczy dla mnie i mojej sytuacji. Mam nadzieję, że to komuś pomoże.
 8
Author: jenkizenki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-06 16:31:19

Tutaj można sprawdzić, czy podany jest tylko jeden parametr, w przeciwnym razie należy zamknąć skrypt:

[ "$#" -ne 1 ] && echo "USAGE $0 <PARAMETER>" && exit
 1
Author: panticz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-12 08:55:37

Jeśli chcesz być po bezpiecznej stronie, polecam użyć getopts.

Oto mały przykład:

    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

Zobacz więcej szczegółów tutaj na przykład http://wiki.bash-hackers.org/howto/getopts_tutorial

 0
Author: IsaacE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-12 13:15:03

Jest tu wiele dobrych informacji, ale chciałem dodać prosty fragment, który uważam za przydatny.

Czym się różni od niektórych powyżej?

  • drukuje użycie na stderr, co jest bardziej odpowiednie niż drukowanie na stdout
  • Return with exit code mentioned in this other answer
  • nie tworzy jednego linera...
_usage(){
    _echoerr "Usage: $0 <args>"
}

_echoerr(){
    echo "$*" >&2
}

if [ "$#" -eq 0 ]; then # NOTE: May need to customize this conditional
    _usage
    exit 2
fi
main "$@"

 0
Author: ngenetzky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-03 16:56:19

Należy dodać spacje między warunkiem testu:

if [ $# -ne 1 ]; 
    then echo "illegal number of parameters"
fi
Mam nadzieję, że to pomoże.
 -1
Author: Fabricio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-19 01:23:51