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? 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
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.
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
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
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:
- przetestuj zmienną bash pod kątem wielkości parametrów $ # not equals 1 (nasza liczba poleceń podrzędnych)
- if true then call usage () function and exit with status 1
- else call main () function
}} Uwaga:
- usage () może być po prostu prostym echo "$0: params "
- main może być jednym długim skryptem
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.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
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
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 "$@"
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.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