Zárójelek az aritmetikában: 3 * (2 + 1)

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

  • +1 Még olvashatóbbak! Feltettem a kérdésemet és a választ, csak gondoltam, hogy hasznos lehet Linux-társaimnak, de most rengeteg hasznot húzok a többi válaszból 🙂
  • Ott ‘ nincs ok a let haszná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 a a=$((3 * (2 + 1))) oldalt hordozhatóvá.
  • I ‘ nem mondom, hogy ‘ s téves, én ‘ m csak azt mondom, hogy nem szabad használni, mivel vannak jobb alternatívák (az egyik az olvashatóságra ((a = 3 * (2 + 1) )), az egyik a hordozhatóságért a=$((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ő .
  • @St é phaneChazelas: Frissítettem a válaszomat!
  • Mindig használtam a a=1 $[a+2] vagy a=1 b=2 $[a+b]. Vajon miért kerülik el ezt a szintaxist?

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 (rc alapjá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, expr beé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 ‘ s BASH_REMATCH valami 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á a sort -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 expr parancssorban szereplő jeleket szóközökkel kell elválasztani; így; például a expr 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 

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük