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
(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
‘ sBASH_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á 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
expr
parancssorban 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
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 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?