Kicsit zavarban vagyok, mit csinálnak ezek az operátorok másképp, amikor használt bash-ban (zárójelben, dupla zárójelben, zárójelben és dupla zárójelben).
[[ , [ , ( , ((
Láttam, hogy az emberek használják őket, ha ilyen állítások vannak:
if [[condition]] if [condition] if ((condition)) if (condition)
Megjegyzések
- Kapcsolódó: egy vagy dupla zárójel segítségével – bash
- A zárójelek és zárójelek ‘ nem olyan könnyen kereshetők a dokumentációban, és hogy ‘ s az összes rendelkezésére áll, ha nem ‘ nem tudja a funkciók nevét.
Válasz
Bourne-szerű héjakban egy if utasítás általában úgy néz ki, mint
if command-list1 then command-list2 else command-list3 fi
A then záradék akkor kerül végrehajtásra, ha a parancsok listája nulla. Ha a kilépési kód nem nulla, akkor a else záradék végrehajtásra kerül. A command-list1 lehet egyszerű vagy összetett. Ez lehet például egy vagy több csővezeték sorozata, amelyet az ;, &, &&, || vagy újsor. Az alább látható if feltételek csak a command-list1 speciális esetei:
-
if [ condition ][a hagyományostestparancs másik neve. A[/testegy szabványos POSIX segédprogram. Minden POSIX héj beépített (bár ezt a POSIX² nem igényli). Aztestparancs beállít egy kilépési kódot és azifutasítást A tipikus tesztek az, hogy létezik-e fájl, vagy az egyik szám egyenlő-e a másikkal. -
if [[ condition ]]Ez egy új, továbbfejlesztett változat a
test¹ verzióhoz a ksh tól, amely bash , zsh , yash , busybox sh is támogatja. Ez a[[ ... ]]konstrukció egy kilépési kódot is beállít, és azifutasítás ennek megfelelően jár el. Kiterjesztett szolgáltatásai között tesztelheti, hogy egy karakterlánc megfelel-e egy helyettesítő mintának (nem a busybox sh ban). -
if ((condition))Egy másik ksh kiterjesztés, amelyet a bash és a zsh is támogat. Az aritmetika eredményeként beállítunk egy kilépési kódot, és az
ifutasítás megfelel rothadóan. Ha az aritmetikai számítás eredménye nem nulla, akkor egy nulla (igaz) kilépési kódot ad vissza. A[[...]]-hez hasonlóan ez az űrlap sem POSIX és ezért nem hordozható. -
if (command)Ez egy alhéjban futtatja a parancsot. Amikor a parancs befejeződik, beállít egy kilépési kódot, és az
ifutasítás ennek megfelelően működik.Az ilyen alhéj használatának tipikus oka az, hogy korlátozza a
commandhacommandváltozó hozzárendelésre vagy egyéb változásra van szükség a shell környezetében. Ezek a változások nem maradnak meg az alhéj befejezése után. -
if commandparancs végrehajtásra kerül, és az
ifutasítás működik a kilépési kódja szerint.
¹ bár nem igazán parancs, hanem egy speciális shell konstrukció, amelynek saját szintaxisa van a normál parancs szintaxisától, és jelentősen változik a shell implementációk között
² A POSIX megköveteli, hogy legyen önálló test és [ segédprogramok azonban a rendszeren, bár a [ esetén számos Linux disztribúció ismert, hogy m használja.
Megjegyzések
- Köszönjük, hogy felvette az 5. lehetőséget. Ez a ‘ kulcs ahhoz, hogy megértsük, hogyan működik ez, és meglepően nem használják ki.
- Ne feledje, hogy a
[valójában egy bináris, nem pedig belső parancs vagy szimbólum. Általában/bin-ban él. - @JulienR. valójában a
[beépített, mint aztest. Kompatibilitási okokból bináris verziók érhetők el. Nézze meg ahelp [és ahelp test. - Érdemes megjegyezni, hogy míg ((nem POSIX,
$((azaz a számtani kiterjesztés ‘ könnyen összetéveszthető. Gyakran megoldást jelent a[ $((2+2)) -eq 4 ]az aritmetika felhasználása a feltételes állításokban - bárcsak többször is fel tudnám szavazni ezt a választ. Tökéletes magyarázat.
Válasz
-
(…)zárójelben egy alhéj . Ami bennük van, az nem olyan kifejezés, mint sok más nyelvben. Ez a parancsok listája (csakúgy, mint a külső zárójelben). Ezeket a parancsokat külön alfolyamatban hajtják végre, így a zárójelben végrehajtott bármilyen átirányítás, hozzárendelés stb. Nincs hatással a zárójelen kívülre.- Vezetővel dollárjel,
$(…)egy parancs helyettesítése : a zárójelben van egy parancs, és a parancs kimenete a parancssor részeként használják (extra kibővítések után, kivéve, ha a helyettesítés kettős idézőjelek között van, de ez “s egy másik történet ).
- Vezetővel dollárjel,
-
{ … }zárójelek olyanok, mint a zárójelek, mivel csoportosítják a parancsokat, de csak az elemzést befolyásolják, a csoportosítást nem. Ax=2; { x=4; }; echo $xprogram 4-et nyomtat, míg azx=2; (x=4); echo $x2-et. (A kulcsszavak nak a zárójeleket is le kell határolni, és a parancs pozíciójában található (innen a szóköz{és a;után}előtt található) zárójelben nincs “t”. Ez csak egy szintaxis furcsa.)- Vezető dollárjel esetén a
${VAR}egy paraméterbővítés , kibővül egy változó értékére, lehetséges extra transzformációkkal. Aksh93héj a${ cmd;}parancsot is olyan parancscsere formaként támogatja, amely nem hoz létre alhéjat.
- Vezető dollárjel esetén a
-
((…))kettős zárójel vesz körül egy számtani utasítást , vagyis az egész számokat kiszámítja, más programozási nyelvekhez hasonló szintaxis. Ezt a szintaxist többnyire hozzárendelésekhez és feltételekhez használják. Ez csak a ksh / bash / zsh fájlban létezik, a sima sh-ben nem.- Ugyanezt a szintaxist használják az aritmetikai kifejezésekben is
$((…)), amelyek kibővülnek a kifejezés egész értékéig.
- Ugyanezt a szintaxist használják az aritmetikai kifejezésekben is
-
[ … ]zárójelek veszik körül feltételes kifejezések . A feltételes kifejezések többnyire operátorokra épülnek, például a-n "$variable"tesztelheti, hogy egy változó üres-e, és-e "$file"annak ellenőrzésére, hogy létezik-e fájl. Vegye figyelembe, hogy mindegyik körül szóközre van szükség operátor (pl.[ "$x" = "$y" ], nem), és szóköz vagy karakter, például[ "$x"="$y" ];mind a zárójelben, mind azon kívül (pl.[ -n "$foo" ], nem).[-n "$foo"] -
[[ … ]]a dupla zárójel a feltételes kifejezések alternatív formája a ksh / bash / zsh fájlban, néhány további funkcióval, például írhat[[ -L $file && -f $file ]]annak tesztelésére, hogy egy fájl szimbolikus hivatkozás-e egy szokásos fájlra, míg az egyes zárójelek[ -L "$file" ] && [ -f "$file" ]-et igényelnek. Lásd: Miért működik az idézőjel nélküli szóköz nélküli paraméterbővítés dupla zárójelben [[de nem egy zárójelben [? ] további információk erről a témáról.
A héjban a minden parancs feltételes parancs: minden parancsnak visszatérési állapota van, amely vagy 0 jelzi a sikert, vagy egy egész szám 1 és 255 között (és egyes héjakban potenciálisan több is) kudarc. A [ … ] parancs (vagy [[ … ]] szintaxis forma) egy adott parancs, amelyet szintén be lehet írni: test … és akkor sikeres, ha létezik fájl, vagy ha egy karakterlánc nem üres, vagy ha egy szám kisebb, mint egy másik, stb. A ((…)) szintaxis űrlap sikeres, ha egy szám nem nulla .Íme néhány példa a shell parancsfájl feltételfeltételeiről:
-
Tesztelje, hogy a
myfiletartalmazza-e ahello:if grep -q hello myfile; then … -
Ha
mydirkönyvtár, váltson és csináld a következőket:if cd mydir; then echo "Creating mydir/myfile" echo "some content" >myfile else echo >&2 "Fatal error. This script requires mydir to exist." fi -
Tesztelje, van-e
myfilenevű fájl az aktuális könyvtárban:if [ -e myfile ]; then … -
Ugyanaz, de lógó szimbolikus linkeket is tartalmaz:
if [ -e myfile ] || [ -L myfile ]; then … -
Tesztelje, hogy a
xértéke (amelyet numerikusnak feltételezünk) legalább 2, hordozhatóan:if [ "$x" -ge 2 ]; then … -
Ellenőrizze, hogy az
xértéke (amely numerikusnak van feltételezve) legalább 2, a bash / ksh / zsh fájlban:if ((x >= 2)); then …
Megjegyzések
- Ne feledje, hogy az egyes zárójelek a
-a-t támogatják a&&, így írhatunk:[ -L $file -a -f $file ], amely ugyanannyi karakter a zárójelben, az extra[és]… - @AlexisWilke A
-aés a-ooperátorok problémás, mert hibás elemzéshez vezethetnek, ha az érintett operandusok egy része operátornak tűnik. Ezért ‘ ezért nem említem őket: nulla előnyük van, és don ‘ t mindig működnek. És soha ne írj nem idézett változóbővítést jó ok nélkül:[[ -L $file -a -f $file ]]rendben van, de egyes zárójelekkel[ -L "$file" -a -f "$file" ]-re van szükség (ami rendben van, pl. Ha$filemindig a következővel kezdődik:/vagy./). - Vegye figyelembe, hogy ez ‘ s
[[ -L $file && -f $file ]](nem-aa[[...]]változat).
Válasz
[ vs [[
Ez a válasz a [ vs [[ a kérdés részhalmaza.
Néhány különbség a Bash 4.3.11-ben:
-
POSIX vs Bash kiterjesztés:
-
[a POSIX -
[[egy Bash kiterjesztés ihlette f rom Korn shell
-
-
rendes parancs vs mágia
-
[csak egy furcsa névvel ellátott rendes parancs.]csak a[utolsó argumentuma.
Az Ubuntu 16.04 tulajdonképpen rendelkezik egy futtatható fájllal a
/usr/bin/[oldalon a coreutils , de a bash beépített verziója elsőbbséget élvez.Semmi sem változik úgy, ahogyan Bash elemzi a parancsot.
Különösen a
<átirányítás,&&és||több parancs összefűzése,( )generál alhéjak, hacsak nem kerüli el a\, és a szó kibővítése a szokásos módon történik.-
[[ X ]]egyetlen olyan konstrukció, amely miatt aXvarázslatosan elemezhető.<,&&,||és()speciálisan kezelik, és a szófelosztási szabályok eltérőek.Vannak további különbségek is, például
=és=~.
bash nyelven:
[egy beépített parancs, és[[egy kulcsszó: https://askubuntu.com/questions/445749/whats-the-difference-between-shell-builtin-and-shell-keyword -
-
<-
[[ a < b ]]: lexikográfiai összehasonlítás -
[ a \< b ]: Ugyanaz, mint fent.\szükséges, különben átirányítást hajt végre, mint bármely más parancsot. Bash kiterjesztés. -
expr x"$x" \< x"$y" > /dev/nullvagy[ "$(expr x"$x" \< x"$y")" = 1 ]: POSIX megfelelői, lásd: https://stackoverflow.com/questions/21294867/how-to-test-strings-for-lexicographic-less-than-or-equal-in-bash/52707989#52707989
-
-
iv
&&és||-
[[ a = a && b = b ]]: igaz, logikus és -
[ a = a && b = b ]: szintaxis hiba,&&AND parancs elválasztóként értelmezvecmd1 && cmd2 -
[ a = a ] && [ b = b ]: POSIX megbízható megfelelője -
[ a = a -a b = b ]: majdnem egyenértékű, de a POSIX elavult, mert őrült és meghiúsul aavagybegyes értékeknél, például!vagy(amelyet logikai műveletekként értelmeznének
-
-
(-
[[ (a = a || a = b) && a = b ]]: hamis. A( )nélkül igaz lenne, mert[[ && ]]nagyobb elsőbbséggel rendelkezik, mint a[[ || ]] -
[ ( a = a ) ]: szintaxis hiba,()alhéjként értelmezve -
[ \( a = a -o a = b \) -a a = b ]: egyenértékű, de(),-aés-oelavult POSIX. A\( \)nélkül igaz lenne, mert a-a-nek nagyobb az elsőbbsége, mint a-o -
{ [ a = a ] || [ a = b ]; } && [ a = b ]nem elavult POSIX-megfelelője. Ebben a konkrét esetben azonban írhattunk volna csak:[ a = a ] || [ a = b ] && [ a = b ], mert a||és&&a shell operátorok azonos prioritással rendelkeznek, ellentétben a[[ || ]]és[[ && ]]és-o,-aés[
-
-
szófelosztás és fájlnév-generálás kibővítéskor (split + glob )
-
x="a b"; [[ $x = "a b" ]]: igaz, idézőjelek nem szükségesek -
x="a b"; [ $x = "a b" ]: szintaxis hiba, kibővül[ a b = "a b" ] -
x="*"; [ $x = "a b" ]: szintaktikai hiba, ha az aktuális könyvtárban egynél több fájl van . -
x="a b"; [ "$x" = "a b" ]: POSIX megfelelője
-
-
=-
[[ ab = a? ]]: igaz, mert minta egyezik (* ? [varázslat). Nem terjed ki f-re iles az aktuális könyvtárban. -
[ ab = a? ]:a?glob kibővül. Tehát az aktuális könyvtárban található fájloktól függően igaz vagy hamis lehet. -
[ ab = a\? ]: hamis, nem globális kiterjesztés -
=és==megegyezik mind a[, mind a[[, de a==egy Bash kiterjesztés. -
case ab in (a?) echo match; esac: POSIX megfelelője -
[[ ab =~ "ab?" ]]: hamis, elveszíti a varázslatot a""vel a Bash 3.2 és újabb verziókban, és ha a bash 3.1 kompatibilitás nem engedélyezett (mint például aBASH_COMPAT=3.1) -
[[ ab? =~ "ab?" ]]: igaz
-
-
=~-
[[ ab =~ ab? ]]: true, POSIX kiterjesztett szabályos kifejezés egyezés,?nem bővül globálisan -
[ a =~ a ]: szintaktikai hiba. Nincs bash megfelelője. -
printf "ab\n" | grep -Eq "ab?": POSIX egyenértékű (csak egysoros adatok) -
awk "BEGIN{exit !(ARGV[1] ~ ARGV[2])}" ab "ab?": POSIX megfelelője.
-
Javaslat: mindig használja a []
Minden látott [[ ]] konstrukcióhoz vannak POSIX-ekvivalensek.
Ha a [[ ]] fájlt használja, akkor:
- elveszíti a hordozhatóságot
- kényszerítse az olvasót, hogy megtanulja egy másik bash kiterjesztés fortélyait. A
[csak egy rendes parancs furcsa névvel, külön szemantikával nem jár.
A Stéphane Chazelas a fontos javításokért és kiegészítésekért.
Megjegyzések
- @St é phaneChazelas köszönöm az információt! Én ‘ hozzáadtam a válaszhoz a
expr-t. A ” Bash ex A feszültség ” nem azt jelenti, hogy Bash volt az első héj, amely hozzáadott némi szintaxist, a POSIX sh vs Bash megtanulása már elég ahhoz, hogy megőrjítsen. - Lásd
man testha megpróbáltadman [és elveszett. Ez megmagyarázza a POSIX variánst. - Javítás:
]a[parancs argumentuma, de nem ‘ ne akadályozza meg a további érvek használatát. A]-nekutolsó argumentumnak kell lennie[-ig, de előfordulhat a tesztkifejezés részeként is. Például aif [ "$foo" = ] ]; thenteszteli, hogy afoováltozó értéke “] ” (mintif [ ] = "$foo" ]; then).- Köszönöm, @GordonDavisson, ‘ nem tudom ezt, javítva.
- @ tgm1024 – Monica rosszul bánt, ez szintén érvényes szempont.
Válasz
A
(list)lista alhéj környezetben kerül végrehajtásra (lásd alább a PARANCS VÉGREHAJTÁS KÖRNYEZETÉT). A shell környezetét befolyásoló változó hozzárendelések és beépített parancsok a parancs befejezése után sem maradnak érvényben. A visszatérési állapot a lista kilépési állapota.Más szavakkal, meg kell győződnie arról, hogy bármi is történik a „listában” (például egy
cd), annak nincs hatása a(és). Az egyetlen dolog, amelyik kiszivárog, az az utolsó parancs kilépési kódja, vagyset -eaz első hibát generáló parancs (más mint néhány, példáulif,whilestb.)((expression))A kifejezést az alábbiakban az ARITMETIKAI ÉRTÉKELÉS alatt leírt szabályok szerint értékeljük. Ha a kifejezés értéke nem nulla, akkor a visszatérési állapot 0; különben a visszatérési állapot értéke 1. Ez pontosan megfelel a ” kifejezés ” kifejezésnek.Ez egy bash kiterjesztés, amely lehetővé teszi matematika készítését. Ez némileg hasonlít a
exprhasználatához aexprminden korlátozása nélkül (például ha mindenhol szóköz van, elkerülhető a*stb.)[[ expression ]]0 vagy 1 állapotot ad vissza, a a feltételes kifejezés kifejezésének értékelése. A kifejezések az alábbiakban a FELTÉTELES KIFEJEZÉSEK alatt ismertetett primerekből állnak. A [[és]] közötti szavakra nem történik szófelosztás és útvonalnagyság; A tilde kiterjesztése, a paraméterek és a változó kiterjesztése, az aritmetikai kiterjesztés, a parancsok helyettesítése, a folyamat helyettesítése és az idézetek eltávolítása történik. A feltételes operátorokat, mint például az -f, nem szabad megadni, hogy felismerhetők legyenek elsődlegesek.A [[használatával a < és > operátorok lexikografikusan rendezik az aktuális területi beállításokat. = “ad58fece9c”>
ajánlatok, de erősebbek.
[ expr ]0 (igaz) vagy 1 (hamis) a feltételes kifejezés kiértékelésétől függően. Minden operátornak és operátornak külön argumentumnak kell lennie. A kifejezések a FELTÉTELES KIFEJEZÉSEK alatt a fent leírt primerekből állnak. A test nem fogad el semmilyen beállítást, és nem fogadja el, illetve nem veszi figyelembe a – argumentumot sem, amely az opciók végét jelzi.[…]
Ez hívja az
test-t. Valójában a régi időkben a[szimbolikus link volt aztestlinkre. Ugyanúgy működik, és ugyanazok a korlátai vannak. Mivel egy bináris ismeri a nevet, amellyel elindították, a tesztprogram[néven tudja tudni, hogy mikor indult, és figyelmen kívül hagyhatja az utolsó paraméterét, amely várhatóan]. Fun Unix trükkök.Ne feledje, hogy
bashesetén[éstestbeépített funkciók (amint azt egy megjegyzés említi), mégis nagyjából ugyanazok a korlátozások érvényesek.Megjegyzések
- Bár
testés[természetesen beépített parancsok a Bash-ban, de valószínűleg ‘ valószínűleg külső bináris is létezik. - A
[külső binárisja nem szimbolikus link atest-hez a legtöbb modern rendszerben . - Valahogy mulatságosnak találom, hogy két külön bináris fájlt hoznak létre, amelyek mindkettőnek pontosan megvan, amire szükségük van, ahelyett, hogy csak kombinálnák őket és adnának pár feltételeset. Bár valójában a
strings /usr/bin/testazt mutatja, hogy a súgószövege is benne van, ezért nem tudom, hogy mit mondjak ‘. - @ Random832 Értelmezem a GNU logikáját a váratlan arg0 viselkedés elkerülése érdekében, de a POSIX követelményekről, nem lennék ennyire igenlő. Míg a
testparancsnak nyilvánvalóan önálló fájl alapú parancsként kell léteznie a szabvány szerint, semmi benne nem mondja ki, hogy[változatát is így kell megvalósítani. Például a Solaris 11 nem biztosít ‘ semmilyen[futtatható fájlt, de ennek ellenére teljes mértékben megfelel a POSIX szabványoknak - (az 1. kilépés) a zárójeleken kívüli hatással bír.
Válasz
Néhány példa:
Hagyományos teszt:
foo="some thing" # check if value of foo is not empty if [ -n "$foo" ] ; then... if test -n "$foo" ; then...
test és a [ parancsok, mint minden más, ezért a változó szavakra van felosztva, hacsak nem idézőjelekben szerepelnek.
Új stílusú teszt
[[ ... ]] egy (újabb) speciális héjszerkezet, amely egy kicsit másképp működik, a legkézenfekvőbb az, hogy nem “t-split-változók:
if [[ -n $foo ]] ; then...
Néhány dokumentáció a [ és [[ itt .
Számtani teszt:
foo=12 bar=3 if (( $foo + $bar == 15 )) ; then ...
“Normál “parancsok:
A fentiek mindegyike úgy működik, mint a normál parancsok, és if bármilyen parancsot felvehet:
# grep returns true if it finds something if grep pattern file ; then ...
Több parancs:
agy több parancsot is használhatunk. A parancsok halmazának ( ... ) beillesztése alhéjban futtatja őket, létrehozva a shell állapotának (munkakönyvtár, változók) ideiglenes másolatát. Ha szükségünk van rá valamely program ideiglenes futtatása egy másik könyvtárban:
# this will move to $somedir only for the duration of the subshell if ( cd $somedir ; some_test ) ; then ... # while here, the rest of the script will see the new working # directory, even after the test if cd $somedir ; some_test ; then ...
Válasz
Parancsok csoportosítása
A Bash kétféle módon csoportosíthatja az egységként végrehajtandó parancsok listáját.
( list ) A parancsok listájának zárójelek közé helyezése alhéjkörnyezet létrehozását eredményezi, és a listában szereplő összes parancs végrehajtása abban az alhéjban történik. alhéjban végrehajtva a változó hozzárendelések nem maradnak érvényben az alhéj befejezése után.
$ a=1; (a=2; echo "inside: a=$a"); echo "outside: a=$a" inside: a=2 outside: a=1
{ list; } a göndör zárójelek közötti parancsok listája a lista végrehajtását az aktuális shell környezetben hajtja végre . Nincs létrehozva alhéj. A pontosvessző (vagy új sor) következő lista kötelező. Forrás
${} Parameter expansion Ex: ANIMAL=duck; echo One $ANIMAL, two ${ANIMAL}s $() Command substitution Ex: result=$(COMMAND) $(()) Arithmetic expansion Ex: var=$(( 20 + 5 ))
Feltételes konstrukciók
Egységes konzol ie []
Összehasonlításhoz ==, !=, <, és > és ezeket fel kell használni, és numerikus összehasonlítás céljából eq, ne,lt és gt kell használni.
Továbbfejlesztett zárójelek ie [[]]
A fenti példákban csak egy zárójeles zárójelet használtunk a feltételes kifejezés becsatolásához, de a bash kettős zárójelet tesz lehetővé, amely az egy zárójeles szintaktika továbbfejlesztett változataként szolgál.
Összehasonlításként a ==, !=, <, és a > szó szerint használható.
-
[a teszt parancs szinonimája. Még akkor is, ha a héjba van építve, új folyamatot hoz létre. -
[[a továbbfejlesztett változata, amely kulcsszó, nem program . -
[[KornésBash. / li>