Implicit megtérülés a bash függvényekben?

Mondjuk, hogy van egy ilyen bash funkcióm:

gmx(){ echo "foo"; } 

implicit módon fog ez a függvény adja vissza a echo parancs kilépési értékét, vagy a return szükséges?

gmx(){ echo "foo"; return $? } 

Feltételezem, hogy a bash működik, a bash függvény utolsó parancsának kilépési állapota az, amelyik “visszaküldik”, de nem 100% -ban biztos.

Válasz

return válasz explicit t ad vissza egy shell függvényből vagy„ dot script ”-ből (forrásból származó szkript). Ha a return nincs végrehajtva, akkor a shell függvény vagy a dot szkript végén implicit visszatérés történik.

Ha return paraméter nélkül kerül végrehajtásra, ez egyenértékű a legutóbb végrehajtott parancs kilépési állapotának visszaadásával.

Így működik a return az összes POSIX-ban kagyló.

Például

gmx () { echo "foo" return "$?" } 

ezért egyenértékű a következővel:

gmx () { echo "foo" return } 

amely megegyezik a

gmx () { echo "foo" } 

Általában nagyon ritkán kell $? egyáltalán. Erre valójában csak akkor van szükség, ha későbbi felhasználásra el kell mentenie, például ha többször is meg kell vizsgálnia az értékét (ebben az esetben egy változóhoz rendelné az értékét, és egy sor tesztet hajtana végre rajta). / p>

megjegyzések

  • A return használat egyik hátránya, hogy a f() (...; cmd; return) megakadályozza azt az optimalizálást, amelyet néhány kagyló futtat a cmd futtatásával az alhéjjal azonos folyamatban. Sok héj esetén ez azt is jelenti, hogy a függvény kilépési állapota nem ‘ nem hordozza azt az információt, amelyet a (A legtöbb héj ‘ egyébként sem tudja lekérni ezeket az információkat).
  • Ne feledje, hogy a pdksh és néhány származéka (például az OpenBSD sh vagy posh), akkor ‘ szükség van return -- "$?" az utolsó parancs egy olyan függvény volt, amely negatív számot adott vissza. A mksh (szintén a pdksh alapján) tiltja a függvények negatív értékek visszaadását.
  • köszönöm, hogy ez segít, azt hiszem, nem ‘ t megértem, hogy a return x másképp működik, mint a exit x … csak azt tudom, hogy return x nem fog kilépni az aktuális folyamatból.
  • @AlexanderMills Nos, ‘ az, amit mondtam: return függvényből vagy dot szkriptből való visszatérésre szolgál. exit valami egészen mást tesz (lezár egy folyamatot).
  • igen, ennek van értelme, azt hiszem, kezdem jobban kezelni ezt

Válasz

A bash(1) man oldalról:

A végrehajtáskor a függvény kilépési állapota a törzsben utoljára végrehajtott parancs kilépési állapota.

Megjegyzések

  • helyes, és ennek lehet következménye, hogy a return utasítás nem más, mint a kilépési állapot?
  • Gondolom return egy beépített parancs – bár a return 1 eltér, mint a exit 1 stb., Így
  • ” return [n]: A függvény leállítja a végrehajtást és visszaadja az n által megadott értéket a hívójának. Ha n el van hagyva, akkor a visszatérési állapot a függvénytestben végrehajtott utolsó parancs állapotának felel meg. ” (ugyanott) Tehát, return a függvény kilépési állapotát egy adott értékre kényszeríti, ha meg van adva.
  • @AlexandwrMills Igen, return és mindkettő beépített, kivéve a return csak a funkción belül használható. ‘ Nem szüntetheti meg a szkriptet a return paranccsal. Az Exit állapot az az érték, amelyet a parancs visszaad. A return olyan parancs, amely visszaadja ezt az értéket. Tehát a ” visszatérési utasítás nem más, mint a kilépési állapot “, csak nem egészen pontos. Az egyik egy érték, a másik a parancs plusz érték.
  • @AlexanderMills, return visszatér a függvényből, exit kilép az egész héjból. ‘ pontosan ugyanaz, mint a, mondjuk C-vel return vs. exit(n), vagy return vs. sys.exit() a Pythonban.

Válasz

Csak néhány figyelmeztetést fűzök a már megadott válaszokhoz:

  • Annak ellenére, hogy a return nagyon különleges jelentése van a héjnak, szintaxis szempontjából egy shell beépített parancs és egy return utasítás elemzi, mint bármely más egyszerű parancsot. Tehát ez azt jelenti, hogy mint bármely más parancs argumentumában, az $? is, ha nem idézi, a split + glob tárgya lesz

    Tehát meg kell idézni ezt az $? -t, hogy elkerülje:

    return "$?" 
  • return általában nem fogad el semmilyen beállítást (ksh93 “s elfogadja a szokásos --help, --man, --author … bár). Az egyetlen argumentum, amelyet elvár (opcionális), a visszatérési kód. Az elfogadott visszatérési kódok tartománya változó héjról héjra, és hogy a 0..255-n kívüli értékek megfelelően tükröződnek-e a

héjenként is változik. A részleteket lásd: Alapértelmezett kilépési kód a folyamat leállításakor? .

A legtöbb héj negatív számokat fogad el (végül is az argumentum a _exit() / exitgroup() rendszerhívás int, tehát legalább – 2 31 – 2 31 -1, tehát csak akkor van értelme, hogy a shellek ugyanazt a tartományt fogadják el a funkcióihoz).

A legtöbb shell a waitpid() és társ. API ennek a kilépési állapotnak a lekérdezéséhez, azonban ebben az esetben 0 és 255 közötti számra csonkol, ha tárolva van $?. nem foglalja magában a folyamat ívását, és a waitpid() felhasználásával kilépési állapotát kapta meg, mivel mindez ugyanabban a folyamatban történik, sok héj is utánozza, hogy waitpid() viselkedés a függvények meghívásakor. Ez azt jelenti, hogy akkor is, ha negatív értékkel hívja a return -t, az $? pozitív számot tartalmaz.

Most azon héjak között, amelyek return negatív számokat fogadnak el (ksh88, ksh93, bash, zsh, pdksh és az mksh-től, yash-tól eltérő származékok), van néhány ( pdksh és yash), amelyekre return -- -123 néven kell írni, különben a -123 -t három -1, -2, -3 érvénytelen beállítások.

Mint pdksh és annak de származékok (például az OpenBSD sh vagy posh) megőrzik a negatív számot az $? mezőben, ez azt jelenti hogy az return "$?" művelet kudarcot vall, ha az $? negatív számot tartalmaz (ami akkor történne, amikor az utolsó futtatás parancs negatív számot adó függvény volt. ).

Tehát return -- "$?" jobb lenne ezekben a héjakban. Megjegyezzük azonban, hogy bár a legtöbb kagyló támogatja, ez a szintaxis nem POSIX, és a gyakorlatban nem támogatott mksh és hamu származékokkal.

Összefoglalva tehát: pdksh-alapú héjak, használhat negatív számokat az argumentumokban a függvényekhez, de ha mégis, akkor a return "$@" nem fog működni. Más héjakban return "$@" működni fog, és kerülje a negatív számok (vagy a 0..255-n kívüli számok) argumentumként való használatát a return

  • Minden általam ismert héjban a return hívása a függvény belsejében futó alhéj belsejéből az alhéj kilépését eredményezi (a megadott exit állapot mellett, ha van ilyen vagy az utolsó parancsé) fut), de egyébként nem okoz visszatérést a függvényből (számomra nem világos, hogy a POSIX megadja-e Önnek ezt a garanciát, egyesek szerint a exit -t kell használni a exit alhéjak helyett belső funkciók). Például

    f() { (return 3) echo "still inside f. Exit status: $?" } f echo "f exit status: $?" 

    kimenetet küld:

    still inside f. Exit status: 3 f exit status: 0 
  • Válasz

    Igen, a függvény implicit visszatérési értéke az utoljára végrehajtott végrehajtási állapot parancs. Ez igaz bármely shell parancsfájl bármely pontján. A parancsfájl végrehajtási sorrendjének bármely pontján a jelenlegi kilépési állapot az utoljára végrehajtott parancs kilépési állapota. Még a változó hozzárendelés részeként végrehajtott parancs is: var=$(exit 34). A különbség a függvényekkel szemben az, hogy egy függvény megváltoztathatja a kilépés állapotát a függvény végrehajtása végén.

    A “jelenlegi kilépés állapot” megváltoztatásának alternatív módja az, ha elindít egy alhéjat és kilép a szükséges kilépési állapot:

    $ $(exit 34) $ echo "$?" 34 

    És igen, a kilépés állapota >

    idézni kell:

    $ IFS="123" $ $(exit 34) $ echo $? 4 

    A (exit 34) is működik.
    Néhányan azt állíthatják, hogy egy robusztusabb konstrukciónak $(return 34) -nek kell lennie, és hogy egy kilépésnek “kilépnie” kell a végrehajtandó szkriptből. De $(return 34) nem működik a bármely bas div verzióval. Tehát nem hordozható.

    A kimeneti állapot beállításának legbiztonságosabb módja az, ha azt úgy használjuk, ahogyan azt egy funkció függvényében dolgozták, definiálták és return működtek. :

    exitstatus(){ return "${1:-"$?"}"; } 

    Tehát egy függvény végén. pontosan egyenértékű azzal, hogy vagy nincs semmi, vagy return vagy return "$?". A függvény vége nem feltétlenül jelenti a “függvény utolsó kódsorát”.

    #!/bin/sh exitstatus(){ a="${1:-"$?"}"; return "$a"; } gmx(){ if [ "$1" = "one" ]; then printf "foo "; exitstatus 78 return "$?" elif [ "$1" = "two" ]; then printf "baz "; exitstatus 89 return else printf "baz "; exitstatus 90 fi } 

    Kiírja:

    $ ./script foo 78 baz 89 baz 90 

    A (z) "$?" egyetlen gyakorlati felhasználása, ha vagy az értékét kinyomtatja: echo "$?" ez egy változóban (mivel ez egy efemer érték és minden végrehajtott paranccsal változik): exitstatus=$? (ne felejtsen el idézni a változót olyan parancsokba, mint export EXITSTATUS="$?".

    A return parancsban az érvényes értéktartomány általában 0 és 255 között van, de értse meg, hogy a 126 + n t néhány kagyló a speciális kilépési állapot jelzésére használja, ezért az általános ajánlás a 0-125 használata.

    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