To pytanie ma już odpowiedzi tutaj :
Odpowiedź
Odpowiedz
Często używam „true” i „false”, ponieważ są to również polecenia, które po prostu zwracają odpowiednio sukces i niepowodzenie. Wtedy możesz zrobić
if "$phone_missing"; then ...
Odpowiedź
Oto jeden ze sposobów to, zachowując wartości prawda / fałsz.
phone_missing=false if [ "$phone_missing" != false ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi if [ "$phone_missing" == true ]; then echo "phone_missing is true." fi
Podwójne cudzysłowy wokół $phone_missing
mają chronić przed przypadkami, w których zmienna phone_missing
nie jest w ogóle zdefiniowana. Innym popularnym idiomem, któremu należy się przeciwstawić, jest [ x$phone_missing != xfalse ]
, ale cytaty wydają mi się bardziej naturalne.
Wskazówka znajduje się na stronie pomocy bash
dla test
:
STRING True if string is not empty. ... ! EXPR True if expr is false.
Więc zasadniczo [ $foo ]
będzie prawdziwe, jeśli $foo
nie jest puste. Nie jest prawdziwe ani fałszywe, po prostu niepuste. [ ! $foo ]
jest prawdziwe, jeśli $ foo jest puste lub niezdefiniowane.
Zawsze możesz zmienić kod, aby po prostu ustawić phone_missing
na inny niż – wartość pusta e, co będzie oznaczało prawdę. Jeśli phone_missing
nie jest ustawione (lub puste – phone_missing=""
), będzie to fałsz. W przeciwnym razie powinieneś używać operatorów testujących ciągi znaków (=
i !=
).
Innym drobnym problemem jest przydzial. Masz to jako $phone_missing=true
, podczas gdy powinno to być phone_missing=true
(bez znaku dolara).
Przepraszamy, jeśli to jest trochę gęsty, bo ja jestem. To był długi dzień. 🙂
Odpowiedź
Inne odpowiedzi dały ci rozwiązanie, ale wyjaśnię, co było nie tak z pierwotnym myśleniem.
Zmienne Bash nie mają typów, więc nie ma czegoś takiego jak zmienna boolowska lub wartość taka jak prawda czy fałsz. Zasadniczo wszystkie zmienne basha są po prostu łańcuchami.
Gdy testujesz zmienną / ciąg znaków w bashu bez określania typu testu (-n
lub -z
), domyślnie będzie to test -n
(ciąg znaków o niezerowej długości).
Więc [ "$var" ]
jest odpowiednikiem [ -n "$var" ]
. Dopóki $var
zawiera co najmniej 1 znak, zostanie obliczone jako prawda.
Ponieważ wyrażenie zostało zanegowane, [ ! "$var" ]
jest odpowiednikiem [ ! -n "$var" ]
. Więc jeśli $var
zawiera co najmniej 1 znak, to wyrażenie jest fałszywe.
Ponieważ false
(czyli po prostu ciąg) zawiera 5 znaków, wyrażenie jest fałszywe. Jeśli „nie ma znaczenia, jaki ciąg ustawisz phone_missing
na (true
, 0, 1), wyrażenie będzie zawsze , ponieważ phone_missing
ma różną od zera długość. Jedynym sposobem, aby to true
było phone_missing=""
, ponieważ ma to zerową długość.
Odpowiedź
Nie używaj łańcucha jako wartości logicznej. Użyj liczby całkowitej.
Dane wejściowe:
val=1 ((val)) && echo "true" || echo "false" val=0 ((val)) && echo "true" || echo "false"
Dane wyjściowe:
true false
Źródło :
((wyrażenie))
Wyrażenie jest oceniane zgodnie z zasadami opisanymi poniżej w części OCENA ARYTMETYCZNA. Jeśli wartość wyrażenia jest różna od zera, zwracany jest stan 0; w przeciwnym razie stan powrotu to 1. Jest to dokładnie równoważne z let „wyrażenie”.
Odpowiedź
Zrobiłbym to jako komentarz, aby wesprzeć Jamesa Ko, ale nie miałem przedstawiciela do komentowania ani publicznego głosowania.
Problem polega na tym, że nawiasy [] są notacją do wykonywania testu porównawczego, takiego jak wartość lub równość łańcuchów.
Prawdziwość ciągów w bash dla pustego ciągu wynosi ""
(pusty ciąg) zwraca wartość fałsz (zwraca wartość 1), a każdy niepusty ciąg „fałsz” „prawda „lub” bob „jest twój wujek” zwraca prawdę (zwraca wartość 0).
Możesz to sobie udowodnić:
if [ "foo" ]; then echo true is $?; else echo false is $?; fi
$?
powyżej to specjalna zmienna, która przechowuje stan wyjścia ostatniego polecenia (0 powodzenia i dowolne> 0 dla kodu błędu) i wyświetla true is 0
. Możesz zamienić "foo"
na cokolwiek chcesz, a wynik będzie taki sam, chyba że zastąpisz go pustym ciągiem ""
lub ""
w takim przypadku oceni warunek else i wyprowadzi false is 1
.
Podczas korzystania z [ ] zawiera nawiasy wewnętrzne, na przykład! $ phone_missing jest oceniane, a następnie zwraca 0
dla true lub 1
dla false contro oświadczenie l. Ponieważ nawias ocenia porównania ciągów i wartości, $ phone_missing jest najpierw interpretowane do niepustego łańcucha „false”, który jest oceniany przez [] jako niepusty ciąg (lub prawda), a następnie! odwraca wynik, co powoduje, że instrukcja if otrzymuje fałsz (lub zwraca wartość 1) i pomija treść warunkową wykonującą instrukcję else, jeśli jest obecna.
Jak powiedział James Ko, notacją byłoby po prostu przekazanie zmienna utrzymująca wartość „boolean” w instrukcji sterującej if. Uwaga , że w bash wartości logiczne prawda i fałsz muszą być zapisane małymi literami, jak w: bool_true = true bool_false = false Każda inna wielkość będzie oceniaj jako łańcuchy, a nie logiczne.
Więc używając twojego przykładu i odpowiedzi Jamesa Ko, wyglądałoby to tak:
phone_missing=false echo "missing $phone_missing" if ! $phone_missing then echo "Lost phone at $readabletime" $phone_missing=true fi
lub ja wolą czytelność (składniowo to samo i James Ko „s)
phone_missing=false echo "missing $phone_missing" if ( ! $phone_missing ); then echo "Lost phone at $readabletime" $phone_missing=true fi
Inne odpowiedzi, takie jak Alexios, dosłownie sprawdzają zawartość ciągu. Aby jedno z poniższych oznaczało fałsz:
phone_missing=false if [ "$phone_missing" != false ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi if [ "$phone_missing" == true ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi if [ "$phone_missing" == Bobs_your_uncle ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi
Odpowiedź
Prawidłowa składnia to if ! $bool; then [statements]; fi
.
Przykład:
bool=false if ! $bool; then echo "This is correct!" fi if [ ! $bool ]; then echo "This is wrong!" fi
Wynik: This is correct!
Komentarze