Muszę sprawdzić istnienie argumentu wejściowego. Mam następujący skrypt
if [ "$1" -gt "-1" ]
then echo hi
fi
dostaję
[: : integer expression expected
Jak najpierw sprawdzić argument wejściowy 1, aby sprawdzić, czy istnieje?
Muszę sprawdzić istnienie argumentu wejściowego. Mam następujący skrypt
if [ "$1" -gt "-1" ]
then echo hi
fi
dostaję
[: : integer expression expected
Jak najpierw sprawdzić argument wejściowy 1, aby sprawdzić, czy istnieje?
Odpowiedzi:
To jest:
if [ $# -eq 0 ]
then
echo "No arguments supplied"
fi
$#
Zmienna powie liczbę wejściowych argumentów skrypt została podjęta.
Lub możesz sprawdzić, czy argument jest pustym łańcuchem, czy nie:
if [ -z "$1" ]
then
echo "No argument supplied"
fi
-z
Przełącznik będzie sprawdzić, czy ekspansja „$ 1” jest ciągiem null lub nie. Jeśli jest to łańcuch zerowy, ciało jest wykonywane.
exit 1
na końcu swojego echa wewnątrz bloku if, gdy wymagany jest argument do działania skryptu. Oczywiste, ale warte odnotowania dla kompletności.
programname "" secondarg third
. $#
Check jednoznacznie sprawdza liczbę argumentów.
if [ ! -z "$1" ]; then ...
Lepiej to zademonstrować w ten sposób
if [[ $# -eq 0 ]] ; then
echo 'some message'
exit 1
fi
Zwykle musisz wyjść, jeśli masz za mało argumentów.
exit 1
co zwykle chcesz, i wykorzystuje [[ ]]
test, który (iirc) jest zwykle bardziej rozsądny. Więc dla osób ślepo kopiujących i wklejających kod jest to lepsza odpowiedź.
W niektórych przypadkach musisz sprawdzić, czy użytkownik przekazał argument do skryptu, a jeśli nie, powróć do wartości domyślnej. Jak w skrypcie poniżej:
scale=${2:-1}
emulator @$1 -scale $scale
Tutaj, jeśli użytkownik nie przeszedł scale
jako drugi parametr, -scale 1
domyślnie uruchamiam emulator Androida . ${varname:-word}
jest operatorem ekspansji. Istnieją również inne operatory ekspansji:
${varname:=word}
która ustawia niezdefiniowane varname
zamiast zwracać word
wartość;${varname:?message}
który albo zwraca, varname
jeśli jest zdefiniowany i nie ma wartości null, albo wypisuje message
skrypt i przerywa skrypt (jak w pierwszym przykładzie);${varname:+word}
który zwraca word
tylko jeśli varname
jest zdefiniowany i nie jest pusty; w przeciwnym razie zwraca null.${varname?message}
. Czy dodatkowa :
literówka czy to zmienia zachowanie?
: ${1?"First argument is null"} ${2?"Please provide more than 1 argument"}
Próbować:
#!/bin/bash
if [ "$#" -eq "0" ]
then
echo "No arguments supplied"
else
echo "Hello world"
fi
$#
i 0
?
else
.
foo*
) i dzieleniu słów (tj. dzieleniu zawartości, jeśli wartość zawiera białe spacje). W takim przypadku nie ma potrzeby cytowania, $#
ponieważ oba te przypadki nie mają zastosowania. Cytowanie 0
również nie jest konieczne, ale niektórzy ludzie wolą cytować wartości, ponieważ są one naprawdę ciągami znaków, co czyni je bardziej wyraźnymi.
Innym sposobem na wykrycie, czy argumenty zostały przekazane do skryptu:
((!$#)) && echo No arguments supplied!
Zauważ, że (( expr ))
powoduje to, że wyrażenie jest oceniane zgodnie z regułami arytmetyki powłoki .
Aby wyjść bez jakichkolwiek argumentów, można powiedzieć:
((!$#)) && echo No arguments supplied! && exit 1
Innym (analogicznym) sposobem stwierdzenia powyższego byłoby:
let $# || echo No arguments supplied
let $# || { echo No arguments supplied; exit 1; } # Exit if no arguments!
help let
mówi:
let: let arg [arg ...]
Evaluate arithmetic expressions. ... Exit Status: If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.
exit
który zabija mój proces zsh, używam tego, return
co go nie zabija
((!$#))
uruchamiać podstawianie historii?
Tylko dlatego, że jest więcej punktów bazowych do podkreślenia, dodam, że możesz po prostu przetestować swój ciąg znaków: null:
if [ "$1" ]; then
echo yes
else
echo no
fi
Podobnie, jeśli oczekujesz liczby argów, po prostu przetestuj swój ostatni:
if [ "$3" ]; then
echo has args correct or not
else
echo fixme
fi
i tak dalej z dowolnym arg lub var
Jeśli chcesz sprawdzić, czy argument istnieje, możesz sprawdzić, czy liczba argumentów jest większa lub równa docelowej liczbie argumentów.
Poniższy skrypt pokazuje, jak to działa
#!/usr/bin/env bash
if [ $# -ge 3 ]
then
echo script has at least 3 arguments
fi
produkuje następujące dane wyjściowe
$ ./test.sh
~
$ ./test.sh 1
~
$ ./test.sh 1 2
~
$ ./test.sh 1 2 3
script has at least 3 arguments
$ ./test.sh 1 2 3 4
script has at least 3 arguments
Jako mały Przypominamy, że operatorzy testy numeryczne w bash działa tylko na liczby całkowite ( -eq
, -lt
, -ge
, itd.)
Chciałbym upewnić się, że moje $ vars są ints
var=$(( var + 0 ))
przed ich przetestowaniem, tylko w celu obrony przed błędem „[: liczba całkowita wymagana”.
var=$(printf "%.0f" "$var")
może obsługiwać zmiennoprzecinkowe, ale otrzymuje ciąg niezerowy po otrzymaniu ciągu. Jeśli nie przeszkadza ci awk ta metoda używam wydaje się być najbardziej wytrzymałe egzekwowania liczbę całkowitą: var=$(<<<"$var" awk '{printf "%.0f", $0}')
. Jeśli var nie jest ustawione, domyślnie jest ustawione na „0”. Jeśli var jest liczbą zmiennoprzecinkową, jest zaokrąglana do najbliższej liczby całkowitej. Można również użyć wartości ujemnych.
walidacja funkcji bash liniowej
myFunction() {
: ${1?"forgot to supply an argument"}
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
dodaj nazwę funkcji i użycie
myFunction() {
: ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage: ${FUNCNAME[0]} some_integer"}
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
dodaj sprawdzanie poprawności, aby sprawdzić, czy liczba całkowita
aby dodać dodatkowe sprawdzanie poprawności, na przykład aby sprawdzić, czy przekazany argument jest liczbą całkowitą, zmodyfikuj jeden wiersz sprawdzania poprawności, aby wywołać funkcję sprawdzania poprawności:
: ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage: ${FUNCNAME[0]} some_integer"} && validateIntegers $1 || die "Must supply an integer!"
następnie skonstruuj funkcję sprawdzania poprawności, która sprawdza poprawność argumentu, zwracając 0 w przypadku sukcesu, 1 w przypadku niepowodzenia i funkcję die, która przerywa skrypt w przypadku niepowodzenia
validateIntegers() {
if ! [[ "$1" =~ ^[0-9]+$ ]]; then
return 1 # failure
fi
return 0 #success
}
die() { echo "$*" 1>&2 ; exit 1; }
Jeszcze prościej - po prostu użyj set -u
set -u
upewnia się, że każda zmienna, do której istnieje odwołanie, jest ustawiona, gdy jest używana, więc po prostu ustaw ją i zapomnij
myFunction() {
set -u
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
[ -z "$1" ] && echo "No argument supplied"
Wolę jednowarstwowe, ponieważ są dla mnie łatwiejsze; a także szybciej sprawdzić wartość wyjścia, w porównaniu do używaniaif