Działa to w wierszu poleceń powłoki (bash, myślnik):
[ -z "" ] && echo A || echo B
A
Jednak próbuję napisać skrypt powłoki POSIX , zaczyna się tak:
#!/bin/sh
[ "${#}" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1
readonly raw_input_string=${1}
[ -z "${raw_input_string}" ] && echo "The given argument is empty."; exit 1
I nie wiem dlaczego, ale nie dostaję wiadomości :
Podany argument jest pusty.
jeśli wywołam skrypt w następujący sposób:
./test_empty_argument ""
Dlaczego?
shell-script
arguments
LinuxSecurityFreak
źródło
źródło
if [ X”” = X”$var” ] ; then echo isempty ; fi
[ "" = "$var" ]
działałoby dobrze; cytowany pusty ciąg nie zostanie usunięty z listy argumentów[
. Ale to też nie jest konieczne, ponieważ działa[ -z "$var" ]
również dobrze.Odpowiedzi:
Zauważ, że twoja linia
to jest to samo co
(cytat
;
można w większości przypadków zastąpić znakiem nowej linii)Oznacza to, że
exit 1
instrukcja jest zawsze wykonywana bez względu na liczbę argumentów przekazanych do skryptu. To z kolei oznacza, że wiadomośćThe given argument is empty.
nigdy nie miałaby szansy na wydrukowanie.Aby wykonać więcej niż jedną instrukcję po teście przy użyciu „składni zwarciowej”, zgrupuj instrukcje w
{ ...; }
. Alternatywą jest użycie poprawnejif
instrukcji (która w skrypcie IMHO wygląda na czystszą):Masz ten sam problem z drugim testem.
Jeżeli chodzi o
To działałoby w podanym przykładzie, ale ogólnym
by nie być taka sama jak
Zamiast tego jest bardziej jak
lub
Oznacza to, że jeśli test lub pierwsze polecenie zakończy się niepowodzeniem, drugie polecenie zostanie wykonane, co oznacza, że może wykonać wszystkie trzy zaangażowane instrukcje.
źródło
To:
nie jest:
Ale zamiast tego jest:
Twój skrypt kończy działanie niezależnie od liczby argumentów, które mu przekazałeś.
źródło
Jednym ze sposobów uczynienia go bardziej czytelnym jest zdefiniowanie
die
funkcji (à laperl
), takiej jak:Możesz dodać więcej dzwonków i gwizdków, takich jak kolory, prefiks, numer linii ... w razie potrzeby.
źródło
die
funkcję z wieloma argumentami? (Jeśli tak, czy możesz podać przykład?) Używam prawie identycznejdie
funkcji, ale"$*"
zamiast tego używaj , co może być bardziej tym, czego zamierzasz?"$@"
polega na tym, że pozwala na wieloliniowe wiadomości bez konieczności dodawania dosłownych znaków nowej linii."$*"
do łączenia argumentów spacjami oznacza również, że musisz ustawić$IFS
SPC, aby działał we wszystkich kontekstach, w tym w tych, w których$IFS
został zmodyfikowany. Alternatywnie za pomocąksh
/zsh
możesz użyćprint -r -- "$@"
lubecho -E - "$@"
wzsh
.die
funkcji -type. Pytam: czy w praktyce widziałeś kiedykolwiek kogośdie "unable to blah:" "some error"
, kto pisze , w celu otrzymania 2-liniowego komunikatu o błędzie?die() { IFS=" "; printf >&2 "%s\n" "$*"; exit 1; }
. Czy kiedykolwiek osobiście używałeś tego rodzajudie
funkcji, abyprintf
wygenerować wieloliniowy komunikat o błędzie, przekazując wiele argumentów? A może przekazujesz tylko jeden argument, abydie
dodawał tylko jeden nowy wiersz do wyniku?Często widziałem to jako test na pusty ciąg:
źródło
-a
,-o
,(
i)
jak derectives powiedziećtest
łączyć wiele operacji w jednym wywołaniu są unikane; patrz znaczniki OB w pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html )./bin/sh
, i bezpośredni poprzednik Heirlooma Bourne'a) również go nie miała.