expr nem tűnik zárójelnek (használt a matematikában az operátor prioritásának kimondása):
expr 3 * (2 + 1) bash: syntax error near unexpected token `("
Hogyan fejezzük ki az operátor prioritását a bash-ban?
Válasz
A let bash beépített használatának másik módja:
$ let a="3 * (2 + 1)" $ printf "%s\n" "$a" 9
Megjegyzés
Ahogy @ Stéphane Chazelas rámutatott , az bash mezőben a ((...)) elemet kell használni a expr vagy let az olvashatóság érdekében.
A hordozhatósághoz használja a $((...)) -t, például a @Bernhard válasz .
Megjegyzések
Válasz
Használhatja a számtani bővítést is. >
echo "$(( 3 * ( 2 + 1 ) ))" 9
Személyes véleményem szerint ez egy kicsit szebbnek tűnik, mint a expr használata.
div id = “6b3499fb27”>
Aritmetikai bővítés A számtani bővítés lehetővé teszi egy aritmetikai kifejezés értékelését és az eredmény helyettesítését. Az aritmetikai kiterjesztés formátuma a következő:
$((expression))A kifejezést úgy kezeljük, mintha dupla idézőjelek között lenne, de a zárójelben lévő kettős idézetet nem külön kezeljük. A kifejezés összes tokenje kiterjesztésre kerül a paramétereken, a karakterlánc-bővítésen, a parancsok helyettesítésén és az idézetek eltávolításán. A számtani bővítések beágyazódhatnak.
Az értékelést az alábbiakban, az ARITMETIKAI ÉRTÉKELÉS alatt felsorolt szabályok szerint végezzük. Ha a kifejezés érvénytelen, a bash meghibásodást jelző üzenetet nyomtat, és nem következik be helyettesítés.
Megjegyzések
- Az olvashatóságon kívül nem is szükséges ‘ egy további folyamat elágazása az aritmetika elvégzéséhez; ‘ s maga a héj kezeli.
- Ne feledje, hogy a POSIX héjakban ‘ szó tárgya hasadás, ezért ‘ jó szokás a listakörnyezetben idézni.
- Amikor ezt megpróbálom a bash shell-en, ‘ Illegális változónév. ”
Válasz
Nincs ok a expr használatára a modern héjak számtechnikájában.
A POSIX meghatározza a $((...)) bővítő operátor. Tehát ezt használhatja az összes POSIX-kompatibilis héjban (az összes modern Unix-szerű, dash, bash, yash, mksh, zsh, posh, ksh sh ).
a=$(( 3 * (2 + 1) )) a=$((3*(2+1)))
ksh egy let beépített rendszert is bemutatott átadta ugyanolyan számtani kifejezést, nem terjeszkedik valamivé, hanem kilépési állapotot ad vissza annak alapján, hogy a resolv kifejezés es 0-ra vagy sem, mint például a expr esetén:
if let "a = 3 * (2 + 1)"; then echo "$a is non-zero" fi
Mivel azonban az idézés kényelmetlenné és nem nagyon olvasható (természetesen nem olyan mértékben, mint expr), ksh bevezett egy ((...)) alternatív forma:
if (( a = 3 * (2 + 1) )) && (( 3 > 1 )); then echo "$a is non-zero and 3 > 1" fi ((a+=2))
amely sokkal olvashatóbb, és helyette kell használni.
let és ((...)) csak ksh, zsh és bash.A $((...)) szintaxist kell előnyben részesíteni, ha más héjakra való hordozhatóságra van szükség, expr csak a POSIX előtti Bourne-szerű héjakhoz szükséges (általában a Bourne-héj vagy az Almquist-héj korai változatai).
A nem Bourne-i fronton található néhány héj beépített számtani operátorral:
-
csh/tcsh(valójában az első Unix-héj, beépített aritmetikai kiértékeléssel):@ a = 3 * (2 + 1) -
akanga(rcalapján)a = $:"3 * (2 + 1)" -
történeti megjegyzésként az Almquist shell eredeti verziója, amelyet 1989-ben tettek közzé az useneten,
exprbeépített (valójában egyesítve a következővel:test), de később eltávolították.
Megjegyzések
- Minden nap tanulok valami újat tőled, St é phane. Nagyra értékelem a POSIX shell ismereteidet!
- Mit szólnál a
: $((a = a*2))-hez? - Mi van, ha van egy lebegőpontom? Kifejezésem a = $ ((-14 + 0,2 * (1 + 2 + 3))). A hibakód ” .2 * (1 + 2 + 3) ”
- @Blaise, akkor te ‘ d olyan héjra van szükség, amely lebegőpontokat támogat a
$((...))fájlokban, például zsh, ksh93 vagy yash.
Válasz
expr egy külső parancs, nem speciális shell-szintaxis. Ezért, ha azt szeretné, hogy a expr látja a shell speciális karaktereit, akkor idézve meg kell védenie őket a shell értelmezésétől. Ezenkívül a expr minden számot és operátort külön paraméterként kell megadni. Így:
expr 3 \* \( 2 + 1 \)
Hacsak nem dolgozik az 1970-es vagy 1980-as évekbeli antik unix rendszeren, nagyon kevés oka van a . Régen a héjaknak nem volt beépített módja az aritmetika végrehajtására, és ehelyett a expr segédprogramot kellett hívnia. Az összes POSIX-héj beépített aritmetikával rendelkezik a aritmetikai bővítés szintaxisán keresztül.
echo "$((3 * (2 + 1)))"
A $((…)) konstrukció kibővül az aritmetikai kifejezés eredményére (tizedessel írva). A Bash, csakúgy, mint a legtöbb héj, csak az egész számtani modulo 2 64 (vagy a modulo 2 32 a bash régebbi verziói és néhány más héj 32 bites gépeken) számát támogatja.
A Bash további kényelmi szintaxist kínál , amikor hozzárendeléseket szeretne végrehajtani, vagy tesztelni szeretné, hogy egy kifejezés 0, de nem érdekli az eredmény. Ez a konstrukció a ksh és a zsh fájlokban is létezik, de sima sh-ben nem.
((x = 3 * (2+1))) echo "$x" if ((x > 3)); then …
Az egész számtan mellett a expr néhány karakterlánc-manipulációs funkciót kínál. Ezeket is alátámasztják a POSIX héjak jellemzői, kivéve az egyiket: expr STRING : REGEXP teszteli, hogy a karakterlánc megfelel-e a megadott regexpnek. A POSIX héj ezt nem tudja megtenni külső eszközök, de a bash képes a következővel: [[ STRING =~ REGEXP ]] ( különböző regexp szintaxissal – expr egy klasszikus eszköz, amely BRE-t használ, a bash az ERE-t használja.
Hacsak nem újrafested a szkripteket amelyek 20 éves rendszereken futnak, akkor nem kell tudnia, hogy expr létezett valaha. Használja a héjszámtant.
Megjegyzések
-
expr foo : '\(.\)'szintén kibontja a szöveget.bash‘ sBASH_REMATCHvalami hasonlót ér el. Karakterlánc-összehasonlítást is végez, amelyet a POSIX[nem tesz meg (bár elképzelhető, hogy miként használhatná asort-t). - aláhúzás szintaxis helyőrzőként — Ön Schemer, @Giles? :]
- @RubyTuesdayDONO Nem használtam ‘ itt aláhúzást. Félreolvassa az U + 2026 HORIZONTAL ELLIPSIS-t? Ha igen, próbáljon meg nagyobb betűtípust használni.
- @Giles – oké, igen, csak aláhúzásnak tűnik a betűméretem miatt. számomra a ” Schemer ” kiegészítő, és ‘ nem tetszik az ellipszisnek versus aláhúzás amúgy is megváltoztatja a jelentést … nem kell sziporkázni rajta: /
Válasz
Zárójeleket használjon idézetek:
expr 3 "*" "(" 2 "+" 1 ")" 9
Az idézetek megakadályozzák, hogy a bash a zárójeleket bash szintaxisként értelmezze.
Megjegyzések
- Amit Nicolas szemléltet, de nem magyarázza meg, az az, hogy a
exprparancssorban szereplő jeleket szóközökkel kell elválasztani; így; például aexpr 3 "*" "(2" "+" "1)"nem fog működni . (Továbbá, BTW, valószínűleg nem kell idézned a+-et.) - A zárójelek nem ‘ t kulcsszavak, például
whileés[[, ők ‘ szintaxist. Ha kulcsszavak lennének, nem értelmeznék őket ‘ a parancs argumentumokban. Szüksége van idézőjelekre, hogy a bash ne elemezze őket, hanem ehelyett egy karakterláncot lát.
Válasz
Ha van bc-je ..
echo "3 * (2 + 1)"|bc 9
lethasználatára. ‘ nem szabványosabb vagy hordozhatóbb, mint a(( a = 3 * (2 + 1) ))(mindkettőkshés csak ksh, bash és zsh fájlokban érhetők el, és ‘ kevésbé olvasható vagy könnyen idézhető. Használja aa=$((3 * (2 + 1)))oldalt hordozhatóvá.((a = 3 * (2 + 1) )), az egyik a hordozhatóságérta=$((3 * (2 + 1)))), tehát ‘ nem ön vagy Ön válasza ellen irányuló megjegyzés, hanem az ellen, hogy ez legyen a kiválasztott válasz és a legtöbb gólszerző .a=1 $[a+2]vagya=1 b=2 $[a+b]. Vajon miért kerülik el ezt a szintaxist?