Si at jeg har en bash-funksjon slik:
gmx(){ echo "foo"; }
vil denne funksjonen implisitt returnere utgangsverdien til echo
-kommandoen, eller er det nødvendig å bruke retur?
gmx(){ echo "foo"; return $? }
Jeg antar at veien bash fungerer, utgangsstatusen for den endelige kommandoen til bash-funksjonen er den som blir «returnert», men ikke 100% sikker.
Svar
return
returnerer en eksplisitt fra en skallfunksjon eller» prikkskript «(et hentet skript). Hvis return
ikke utføres, blir det gitt en implisitt avkastning på slutten av skallfunksjonen eller punktskriptet.
Hvis return
kjøres uten en parameter, det tilsvarer å returnere utgangsstatus for den sist utførte kommandoen.
Det er slik return
fungerer i alle POSIX skjell.
For eksempel,
gmx () { echo "foo" return "$?" }
tilsvarer derfor
gmx () { echo "foo" return }
som er det samme som
gmx () { echo "foo" }
Generelt sett er det veldig sjelden du trenger å bruke $?
i det hele tatt. Det er egentlig bare nødvendig hvis du trenger å lagre det for fremtidig bruk, for eksempel hvis du trenger å undersøke verdien flere ganger (i så fall vil du tilordne verdien til en variabel og utføre en serie tester på den variabelen). / p>
Kommentarer
Svar
Fra bash(1)
man-siden:
Når den utføres, er utgangsstatus for en funksjon utgangsstatus for den siste kommandoen som ble utført i kroppen.
Kommentarer
- riktig, og en følge kan være at returuttalelsen ikke er noe mer enn utgangsstatusen?
- Jeg antar
return
er en innebygd kommando – selv omreturn 1
er annerledes ennexit 1
osv. Så - » return [n]: Gjør at en funksjon stopper utførelsen og returnerer verdien som er spesifisert av n til den som ringer. Hvis n er utelatt, er returstatusen den for den siste kommandoen som ble utført i funksjonslegemet. » (ibid) Så,
return
tvinger utgangsstatusen til en funksjon til en bestemt verdi hvis spesifisert. - @AlexandwrMills Ja,
return
ogexit
er begge innebygde, bortsett fra atreturn
bare kan brukes innen funksjon. Du kan ‘ t avslutte et skript medreturn
. Utgangsstatus er verdien kommandoen returnerer.return
er en kommando som returnerer den verdien. Så » returuttalelse er ikke noe mer enn utgangsstatus » er bare ikke helt nøyaktig. Den ene er en verdi, den andre er kommando pluss verdi. - @AlexanderMills,
return
returnerer fra funksjonen,exit
går ut av hele skallet. Det ‘ er nøyaktig det samme som i, si C medreturn
vs.exit(n)
, ellerreturn
vs.sys.exit()
i Python.
Svar
Jeg legger bare til noen forsiktighetsanvisninger i svarene som allerede er gitt:
-
Selv om
return
har en veldig spesiell betydning for skallet, fra et syntakssynspunkt er det en shell-innebygd kommando og en returuttalelse blir analysert som alle andre enkle kommandoer. Så det betyr at$?
når det ikke er sitert, vil bli utsatt for split + globSå du må sitere det
$?
for å unngå det:return "$?"
-
return
godtar vanligvis ikke noe alternativ (ksh93
«s godtar det vanlige--help
,--man
,--author
… skjønt). Det eneste argumentet det forventer (valgfritt) er returkoden. Omfanget av aksepterte returkoder varierer fra skall til skall, og om noen verdi utenfor 0..255 gjenspeiles riktig i
varierer også fra skall til skall. Se Standard utgangskode når prosessen avsluttes? for detaljer om det.
De fleste skjell godtar negative tall (tross alt overføres argumentet til _exit()
/ exitgroup()
systemanrop er en int
, så med verdier som omfatter minst – 2 31 til 2 31 -1, så det er bare fornuftig at skjell aksepterer samme område for funksjonene).
De fleste skjell bruker waitpid()
og co. API for å hente utgangsstatusen, i så fall blir den avkortet til et tall mellom 0 og 255 når lagret i $?
. Selv om du påkaller en funksjon involverer ikke gyting av en prosess og brukte waitpid()
for å hente utgangsstatusen da alt er gjort i samme prosess, mange skjell etterligner også at waitpid()
atferd når man påkaller funksjoner. Hvilket betyr at selv om du ringer return
med en negativ verdi, vil $?
inneholde et positivt tall.
Nå, blant de skjellene hvis return
aksepterer negative tall (ksh88, ksh93, bash, zsh, pdksh og andre derivater enn mksh, yash), er det noen få ( pdksh og yash) som trenger det skrevet som return -- -123
som ellers at -123
blir tatt som tre -1
, -2
, -3
ugyldige alternativer.
Som pdksh og dens de rivativer (som OpenBSD sh
eller posh
) bevarer det negative tallet i $?
at å gjøre return "$?"
vil mislykkes når $?
inneholder et negativt tall (som ville skje når kommandoen for siste kjøring var en funksjon som returnerte et negativt tall ).
Så return -- "$?"
ville vært bedre i de skjellene. Vær imidlertid oppmerksom på at mens den støttes av de fleste skjell, er denne syntaksen ikke POSIX og i praksis ikke støttet av mksh
og askerivater.
Så, for å oppsummere med pdksh-baserte skall, kan du bruke negative tall i argumenter for funksjoner, men hvis du gjør det, vil return "$@"
ikke fungere. I andre skall, return "$@"
fungerer, og du bør unngå å bruke negative tall (eller tall utenfor 0..255) som argumenter for return
.
I alle skjell som jeg kjenner, vil ringing av return
fra innsiden av en subshell som kjører inne i en funksjon, føre til at subshell avsluttes (med den angitte utgangsstatusen hvis noen eller den forrige kommandoen kjøre), men vil ellers ikke føre til at funksjonen returneres (for meg er det uklart om POSIX gir deg den garantien. Noen hevder at exit
skal brukes i stedet for å avslutte subshells innvendige funksjoner). For eksempel
f() { (return 3) echo "still inside f. Exit status: $?" } f echo "f exit status: $?"
vil sende ut:
still inside f. Exit status: 3 f exit status: 0
Svar
Ja, den implisitte returverdien til en funksjon er utgangsstatus for den siste kommando. Det gjelder også når som helst i et skallskript. Når som helst i sekvensen for skriptutførelse, er nåværende utgangsstatus utgangsstatus for den siste kommandoen. Selv kommando utført som en del av en variabel oppgave: var=$(exit 34)
. Forskjellen med funksjoner er at en funksjon kan endre utgangsstatus på slutten av utførelsen av funksjonen.
Den alternative måten å endre «nåværende utgangsstatus» er å starte et underskall og avslutte det med eventuell nødvendig utgangsstatus:
$ $(exit 34) $ echo "$?" 34
Og ja, utgangsstatus utvidelse må siteres:
$ IFS="123" $ $(exit 34) $ echo $? 4
A (exit 34)
fungerer også.
Noen kan hevde at en mer robust konstruksjon skal være $(return 34)
, og at en exit bør «avslutte» skriptet som utføres. Men $(return 34)
fungerer ikke med noen versjon av bash. Så den er ikke bærbar.
Den sikreste måten å angi en utgangsstatus er å bruke den slik den ble designet for å fungere, definere og return
fra en funksjon :
exitstatus(){ return "${1:-"$?"}"; }
Så, til slutt på en funksjon. det tilsvarer nøyaktig å ha enten ingenting eller return
eller return "$?"
. Slutten av en funksjon trenger ikke å bety den «siste kodelinjen til en funksjon».
#!/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 }
Skrives ut:
$ ./script foo 78 baz 89 baz 90
Den eneste praktiske bruken for "$?"
er å enten skrive ut verdien: echo "$?"
eller å lagre det i en variabel (da det er en kortvarig verdi og endring med hver kommando som utføres): exitstatus=$?
(husk å sitere variabelen i kommandoer som export EXITSTATUS="$?"
.
I return
-kommandoen er det gyldige verdiområdet generelt 0 til 255, men forstå at verdiene til 126 + n
brukes av noen skall for å signalisere spesiell utgangsstatus, så den generelle anbefalingen er å bruke 0-125.
return
er at for funksjoner definert somf() (...; cmd; return)
, forhindrer det optimaliseringen som noen få skjell gjør for å kjørecmd
i samme prosess som subshell. Med mange skall betyr det også at utgangsstatusen til funksjonen ikke ‘ t bærer informasjonen om atcmd
er drept når den har (de fleste skjell kan ‘ t hente informasjonen uansett).sh
ellerposh
), du ‘ d trengerreturn -- "$?"
hvis det var sjanse for at den siste kommandoen var en funksjon som returnerte et negativt tall.mksh
(også basert på pdksh) forbyr funksjoner å returnere negative verdier.return x
fungerer annerledes ennexit x
… det eneste jeg vet er atreturn x
vil ikke avslutte den nåværende prosessen.return
brukes til å returnere fra en funksjon eller et punktskript.exit
gjør noe helt annet (avslutter en prosess).