Porozumění booleovským operátorům v bash skriptu [duplikát]

Tato otázka již má odpovědi zde :

Odpověď

Proměnná $phone_missing je řetězec, který obsahuje false. A neprázdný řetězec se vyhodnotí jako true. Viz také http://www.linuxintro.org/wiki/Babe#empty_strings

Komentáře

  • Ah v pořádku. Deklaroval bych tuto proměnnou jako booleovskou (alespoň ne s deklaračním slovem), ale popelová konzole mi to nedovolila ' Také nechci ' porovnávat řetězce. Jak se to dělá správně?
  • stackoverflow.com/questions/2953646/… , ale dávejte pozor: tento člověk PROVÁDÍ řetězcovou proměnnou a stejně jako false i true jsou unixové příkazy.

Odpovědět

Často používám „true“ a „false“, protože jsou to také příkazy, které pouze vracejí úspěch a selhání. Pak můžete provést

if "$phone_missing"; then ... 

odpovědět

Zde je jeden způsob, jak to udělat toto, při zachování hodnot true / false.

 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  

Dvojité uvozovky kolem $phone_missing slouží k ochraně proti případu, kdy proměnná phone_missing není definována vůbec. Dalším společným idiomem, který se proti tomu brání, je [ x$phone_missing != xfalse ], ale nabídky se mi zdají přirozenější.

Nápověda je na stránce bash nápovědy pro test:

 STRING True if string is not empty. ... ! EXPR True if expr is false. 

Takže v zásadě [ $foo ] bude platit, pokud $foo není prázdný. Není pravdivý nebo nepravdivý, pouze neprázdný. [ ! $foo ] je pravda, pokud je $ foo prázdný nebo nedefinovaný.

Svůj kód můžete vždy změnit tak, že phone_missing nastavíte na -prázdná hodnota e, což bude označovat true. Pokud je phone_missing nenastaveno (nebo prázdné – phone_missing=""), bude mít hodnotu false. Jinak byste měli používat operátory testování řetězců (= a !=).

Další drobný problém je zadání. Máte to jako $phone_missing=true, zatímco by to mělo být phone_missing=true (bez dolaru).

Omlouváme se, pokud je trochu hustý, je to proto, že jsem jsem. Byl to dlouhý den. 🙂

Odpověď

Jiné odpovědi vám poskytly řešení, ale vysvětlím, co se stalo s původním myšlením.

Bash proměnné nemají typy, takže neexistuje žádná logická proměnná nebo hodnota jako true nebo false. V zásadě jsou všechny proměnné bash pouze řetězce.

Když testujete proměnnou / řetězec v bash bez určení typu testu (-n nebo -z), použije se výchozí -n (nenulový řetězec délky) testu.

Takže [ "$var" ] je ekvivalentní s [ -n "$var" ]. Pokud $var obsahuje alespoň 1 znak, byl vyhodnocen jako pravdivý.

Protože jste výraz negovali, [ ! "$var" ] je ekvivalentní s [ ! -n "$var" ]. Pokud tedy $var obsahuje alespoň 1 znak, je výraz nepravdivý.

Protože false (což je pouze řetězec) obsahuje 5 znaků, výraz je nepravdivý. Pokud nezáleží na tom, jaký řetězec nastavíte phone_missing na (true, 0, 1), bude výraz vždy false protože je phone_missing nenulová délka. Jediný způsob, jak to udělat true, je phone_missing="" protože to má nulovou délku.

Odpověď

Nepoužívejte řetězec pro boolean. Použijte celé číslo.

Vstup:

val=1 ((val)) && echo "true" || echo "false" val=0 ((val)) && echo "true" || echo "false" 

Výstup:

true false 

Zdroj :

((výraz))

Výraz je vyhodnocen podle pravidel popsaných níže v části ARITMETICKÉ HODNOCENÍ. Pokud je hodnota výrazu nenulová, návratový stav je 0; jinak je návratový stav 1. To je přesně ekvivalent k let „výrazu“.

Odpověď

Udělal bych to jako komentář na podporu Jamese Ko, ale neměl zástupce, který by komentoval nebo veřejně hlasoval.

Problém je v tom, že závorky [] jsou notací pro provádění srovnávacího testu, jako je hodnota nebo rovnost řetězců.

Pravdivost řetězce v bash pro prázdný řetězec je "" (prázdný řetězec) vyhodnocen jako false (návratová hodnota 1) a jakýkoli neprázdný řetězec „false“ „true „nebo„ tvůj strýc “se vyhodnotí jako true (návratová hodnota 0).

To si můžete dokázat pomocí:

 if [ "foo" ]; then echo true is $?; else echo false is $?; fi 

Výše uvedená $? je speciální proměnná, která obsahuje stav ukončení posledních příkazů (0 úspěch a libovolný> 0 pro chybový kód) a na výstupu bude true is 0. "foo" můžete nahradit čímkoli, co chcete, a výsledek bude stejný, kromě případů, kdy jej nahradíte prázdným řetězcem "" nebo "" v takovém případě vyhodnotí podmínku else a výstup false is 1.

Při použití [ ] závorky interní příkaz, jako je! $ phone_missing je vyhodnocen a poté vrátí 0 pro true nebo 1 pro false do if contro l prohlášení. Protože závorka vyhodnocuje srovnání řetězců a hodnot, $ phone_missing se nejprve rozšíří na neprázdný řetězec „false“, který je vyhodnocen [] jako neprázdný řetězec (nebo true) a poté! invertuje výsledek, který má za následek, že příkaz if dostane nepravdivou hodnotu (nebo vrátí hodnotu 1) a přeskočí podmíněné tělo provádějící příkaz else, pokud je k dispozici.

Jak řekl James Ko, notací by bylo předat pouze proměnná, která drží váš „boolean“ s příkazem if control. Všimněte si , že v bash musí být boolean true a false malá písmena jako v: bool_true = true bool_false = false Jakýkoli jiný případ vyhodnotit jako řetězce a ne booleovské.

Takže pomocí vašeho příkladu a odpovědi Jamese Ko by to bylo:

phone_missing=false echo "missing $phone_missing" if ! $phone_missing then echo "Lost phone at $readabletime" $phone_missing=true fi 

nebo jako já dávají přednost čitelnosti (syntakticky stejné a James Ko) s

phone_missing=false echo "missing $phone_missing" if ( ! $phone_missing ); then echo "Lost phone at $readabletime" $phone_missing=true fi 

Další odpovědi, například od Alexiose, doslova kontrolují obsah řetězce. Takže některá z následujících možností by vedla k nepravdivosti:

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 

Odpověď

Správná syntaxe je if ! $bool; then [statements]; fi.

Příklad:

bool=false if ! $bool; then echo "This is correct!" fi if [ ! $bool ]; then echo "This is wrong!" fi 

Výstup: This is correct!

Komentáře

  • Ve vaší odpovědi je jádro pravdy, ale bez jakéhokoli vysvětlení způsobuje více zmatek, než to napraví. Není to nic víc než opakování jedné z předchozích odpovědí. Pokud si nepřejete, aby byla vaše odpověď odstraněna, vysvětlete, proč je správná.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *