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ányostest
parancs másik neve. A[
/test
egy szabványos POSIX segédprogram. Minden POSIX héj beépített (bár ezt a POSIX² nem igényli). Aztest
parancs beállít egy kilépési kódot és azif
utasí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 azif
utasí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
if
utasí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
if
utasítás ennek megfelelően működik.Az ilyen alhéj használatának tipikus oka az, hogy korlátozza a
command
hacommand
vá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 command
parancs végrehajtásra kerül, és az
if
utasí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 $x
program 4-et nyomtat, míg azx=2; (x=4); echo $x
2-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. Aksh93
hé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[ "$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
myfile
tartalmazza-e ahello
:if grep -q hello myfile; then …
-
Ha
mydir
kö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
myfile
nevű 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-o
operá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$file
mindig a következővel kezdődik:/
vagy./
). - Vegye figyelembe, hogy ez ‘ s
[[ -L $file && -f $file ]]
(nem-a
a[[...]]
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 aX
vará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/null
vagy[ "$(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 aa
vagyb
egyes é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-o
elavult 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 test
ha 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" = ] ]; then
teszteli, hogy afoo
vá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 -e
az első hibát generáló parancs (más mint néhány, példáulif
,while
stb.)((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
expr
használatához aexpr
minden 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 aztest
linkre. 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
bash
esetén[
éstest
beé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/test
azt 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
test
parancsnak 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>