GNU/Linux >> Znalost Linux >  >> Linux

Více logických operátorů ((a || B) &&C) a „chyba syntaxe blízko neočekávaného tokenu“?

Pracuji s Bash 3 a snažím se vytvořit podmínku. V C/C++ je to smrtelně jednoduché:((A || B) && C) . V Bash se ukázalo, že tomu tak není (myslím, že autoři Gitu museli přispět tímto kódem, než přešli na jiné snahy).

To nefunguje. Všimněte si, že <0 or 1> není řetězcový literál; znamená to 0 nebo 1 (obecně pochází z grep -i ).

A=<0 or 1>
B=<0 or 1>
C=<0 or 1>
if [ [ "$A" -eq "0" ] || [ "$B" -ne "0" ] ] && [ "$C" -eqe "0" ]; then ... fi

Výsledkem je:

line 322: syntax error near unexpected token `[['

Pak jsem zkusil:

A=<0 or 1>
B=<0 or 1>
C=<0 or 1>
if [ ([ "$A" -eq "0" ]) || ([ "$B" -ne "0" ]) ] && [ "$C" -eq "0" ]; then ... fi

výsledkem je:

line 322: syntax error near unexpected token `[['

Část problému spočívá v tom, že výsledky vyhledávání jsou triviální příklady, nikoli složitější příklady se složenými podmíněnými podmínkami.

Jak provedu jednoduchý ((A || B) && C) v Bash?

Jsem připraven to prostě rozvinout a opakovat stejné příkazy ve více blocích:

A=<0 or 1>
B=<0 or 1>
C=<0 or 1>

if [ "$A" -eq "0" ] && [ "$C" -eq "0" ]; then
    ...
elif [ "$B" -ne "0" ] && [ "$C" -eq "0" ]; then
    ... 
fi

Přijatá odpověď:

Syntaxe bash není podobná C, i když její malá část je inspirována C. Nemůžete jednoduše zkusit napsat kód C a očekávat, že to bude fungovat.

Hlavním bodem shellu je spouštění příkazů. Příkaz s otevřenou hranatou závorkou [ je příkaz, který provede jeden test¹. Můžete to dokonce napsat jako test (bez závěrečné závorky). || a && operátory jsou shellové operátory, kombinují příkazy , nikoli testy.

Takže když píšeš

[ [ "$A" -eq "0" ] || [ "$B" -ne "0" ] ] && [ "$C" -eq "0" ]

který je analyzován jako

[ [ "$A" -eq "0" ] ||
[ "$B" -ne "0" ] ] &&
[ "$C" -eq "0" ]

což je stejné jako

test [ "$A" -eq "0" ||
test "$B" -ne "0" ] &&
test "$C" -eq "0"

Všimli jste si nevyvážených závorek? Ano, to není dobré. Váš pokus se závorkami má stejný problém:falešné závorky.

Syntaxe pro seskupování příkazů dohromady jsou složené závorky. Způsob, jakým jsou složené závorky analyzovány, vyžaduje před nimi úplný příkaz, takže příkaz ve složených závorkách budete muset ukončit novým řádkem nebo středníkem.

if { [ "$A" -eq "0" ] || [ "$B" -ne "0" ]; } && [ "$C" -eq "0" ]; then …

Existuje alternativní způsob, kterým je použití dvojitých závorek. Na rozdíl od jednoduchých závorek jsou dvojité závorky speciální syntaxí shellu. Vymezují podmíněné výrazy. Uvnitř dvojitých závorek můžete použít závorky a operátory jako && a || . Protože dvojité závorky jsou syntaxí shellu, shell ví, že když jsou tyto operátory v hranatých závorkách, jsou součástí syntaxe podmíněného výrazu, nikoli součástí běžné syntaxe příkazu shellu.

if [[ ($A -eq 0 || $B -ne 0) && $C -eq 0 ]]; then …

Pokud jsou všechny vaše testy numerické, existuje ještě další způsob, který vymezuje artihmetické výrazy. Aritmetické výrazy provádějí celočíselné výpočty se syntaxí velmi podobnou C.

if (((A == 0 || B != 0) && C == 0)); then …

Možná se vám bude hodit můj bash bracket primer.

Související:Debian – Zhroucení systému – podivné znaky v syslogu?

[ lze použít v obyčejném sh. [[ a (( jsou specifické pro bash (a ksh a zsh).

¹ Může také kombinovat více testů s booleovskými operátory, ale použití je těžkopádné a má to drobná úskalí, takže to nebudu vysvětlovat.


Linux
  1. Linux C výuka programování, část 11 - Aritmetické, relační a logické operátory

  2. Jak spustit Grep s více a vzory?

  3. Přednost logických operátorů Shell &&, ||?

  1. Načítání sdílených knihoven a využití RAM?

  2. Trap, Err, A Echoing the Error Line?

  3. Ssh na více hostitelů a spustit příkaz?

  1. “Chyba syntaxe u neočekávaného tokenu” Po úpravě .bashrc?

  2. Konfigurace a ladění OpenVAS v Kali Linuxu

  3. Chyba 'Neočekávaný konec souboru' a 'Chyba při importu definice funkce' při spuštění shellscriptu pomocí qsub