Én a Bash 3-zal dolgozom, és megpróbálok feltételeset alkotnak. A C / C ++ verzióban a halott egyszerű: ((A || B) && C)
. A Bash-ban kiderült, hogy nem így van (szerintem a Git-szerzőknek biztosan hozzájárultak ehhez a kódhoz, mielőtt más erőfeszítésekbe kezdtek volna).
Ez nem működik. Vegye figyelembe, hogy az <0 or 1>
nem karakterlánc; 0 vagy 1 értéket jelent (általában grep -i
forrásból származik).
A=<0 or 1> B=<0 or 1> C=<0 or 1> if [ [ "$A" -eq "0" ] || [ "$B" -ne "0" ] ] && [ "$C" -eqe "0" ]; then ... fi
Ennek eredménye:
line 322: syntax error near unexpected token `[["
Ezután megpróbáltam:
A=<0 or 1> B=<0 or 1> C=<0 or 1> if [ ([ "$A" -eq "0" ]) || ([ "$B" -ne "0" ]) ] && [ "$C" -eq "0" ]; then ... fi
ennek eredménye:
line 322: syntax error near unexpected token `[["
A probléma része, hogy a keresési eredmények a triviális példák, és nem az összetett feltételekkel bonyolultabb példák.
Hogyan hajthatok végre egy egyszerű ((A || B) && C)
a Bash-ban?
Készen állok csak kibontani és ugyanazokat a parancsokat több blokkban megismételni:
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
Válasz
A bash szintaxisa nem C-szerű, még akkor is, ha egy kis részét C ihlette. Nem lehet egyszerűen megpróbálni C kódot írni, és elvárni, hogy működjön.
A shell fő célja a parancsok futtatása. Az open-zárójeles parancs [
egy parancs, amely egyetlen tesztet hajt végre¹. Akár test
néven is megírhatja (a záró zárójel nélkül). A ||
és &&
operátorok shell operátorok, parancsokat kombinálnak, nem teszteket.
Tehát, amikor
[ [ "$A" -eq "0" ] || [ "$B" -ne "0" ] ] && [ "$C" -eq "0" ]
ír, akkor a következő elemzés
[ [ "$A" -eq "0" ] || [ "$B" -ne "0" ] ] && [ "$C" -eq "0" ]
ugyanaz, mint
test [ "$A" -eq "0" || test "$B" -ne "0" ] && test "$C" -eq "0"
Figyelje meg a kiegyensúlyozatlan zárójeleket? Igen, ez nem jó. A zárójeles kísérletnek ugyanaz a problémája: hamis zárójelek.
A parancsok együttes csoportosításának szintaxisa zárójel. A zárójelek elemzésének módja teljes parancsot igényel előttük, ezért új vonallal vagy pontosvesszővel kell befejeznie a zárójelek belsejében található parancsot.
if { [ "$A" -eq "0" ] || [ "$B" -ne "0" ]; } && [ "$C" -eq "0" ]; then …
Ott msgstr “” “alternatív mód a dupla zárójelek használata. Az egyes zárójelekkel ellentétben a dupla zárójelek a héj speciális szintaxisa. Elhatárolják a feltételes kifejezéseket . A dupla zárójelben olyan zárójeleket és operátorokat használhat, mint a &&
és ||
. Mivel a dupla zárójel héj szintaxisa, a héj tudja, hogy amikor ezek az operátorok zárójelben vannak, akkor a feltételes kifejezés szintaxisának részét képezik, nem pedig a szokásos shell parancs szintaxisának.
if [[ ($A -eq 0 || $B -ne 0) && $C -eq 0 ]]; then …
Ha az összes teszt numerikus, akkor van még egy módja, amely elhatárolja a műtani kifejezéseket . Az aritmetikai kifejezések egész számításokat végeznek, nagyon C-szerű szintaxissal.
if (((A == 0 || B != 0) && C == 0)); then …
Megtalálhatja az bash zárójelemet alapozó hasznos.
[
használható sima sh-ben. A [[
és a ((
a bash-ra (és a ksh-re és a zsh-re) vonatkoznak.
¹ Ez is kombináljon több tesztet logikai operátorokkal, de ez nehézkes használni, és finom buktatói vannak, ezért nem fogom megmagyarázni.
Megjegyzések
Válasz
Használja a [[
parancsot:
if [[ ( "$A" -eq "0" || "$B" -ne "0" ) && "$C" -eq "0" ]]; then ...
Ha a [
-t részesíti előnyben, akkor a következők működnek:
if [ \( "$A" -eq "0" -o "$B" -ne "0" \) -a "$C" -eq "0" ]; then ...
Megjegyzések
- Köszönöm, Stephen. Esetemben így használtam az első példáját … regex = ' ^ [0-9] + $ ' length = $ {#datearg} ha! [[$ datearg = ~ $ regex & & $ hossz -eq 8]]; akkor echo " hiba: A 8 " száma nem sok; fi
Válasz
Használja a -o
operátort a beágyazott ||. Használhatja a -a
alkalmazást a & & helyettesítésére is, ha más állításokban szükséges. .
EXPRESSION1 -a EXPRESSION2 both EXPRESSION1 and EXPRESSION2 are true EXPRESSION1 -o EXPRESSION2 either EXPRESSION1 or EXPRESSION2 is true if [ "$A" -eq "0" -o "$B" -ne "0" ] && [ "$C" -eq "0" ]; then echo success;fi
Megjegyzések
- Köszönöm. Találkoztam a
-a
és-o
vel, de nem kísérleteztem velük. Valaki a Stack Overflow oldalán azt mondta, hogy kerülje el. Többnyire egyetértettem velük, mivel a szkript kevésbé olvasható használatukkal. - … de inkább hordozható.
- @Kusalananda – Köszönjük a hordozhatósággal kapcsolatos fejfájást. A szkriptnek a Bash 2-től a Bash 4-ig tartó rendszereken kell futnia.
[[ ( "$A" -eq "0" || "$B" -ne "0" ) && "$C" -eq "0" ]]
problémákat okozhat velük kapcsolatban? - Nem lesznek problémák addig, amíg folytatja a
bash
vagy bármely más shell, amely megérti a[[ ... ]]
szót. - Az -a használatának alsó oldala nem ' t rövidzárlat, ha az első kifejezés hamis. Tehát, ha rövidzárlatra támaszkodik, hogy megakadályozza a potenciálisan végzetes 2. kifejezés futását, akkor az -a nem használható. Példa: pastebin.com/zM77TXW1
[[ … ]]
hozzáadva a bash 2.02-ben.((…))
hozzáadva a bash 2.0-hoz.||
és a változás[
-ről[[
és((
-re. Egyenlő elsőbbség a[
-ben (zárójelekkel ellenőrizheti az értékelés sorrendjét), de & & nagyobb prioritással rendelkezik[[
és((
, mint a||
(mint a C-ben).[[ … ]]
vagy$((…))
csak csoportosításra szolgálnak.