Bash fonksiyonlarındaki return
ve exit
ifadeleri arasındaki çıkış kodları arasındaki fark nedir ?
Bash fonksiyonlarındaki return
ve exit
ifadeleri arasındaki çıkış kodları arasındaki fark nedir ?
Yanıtlar:
Gönderen man bash
üzerine return [n]
;
Bir işlevin yürütülmesini durdurmasına ve n ile belirtilen değeri arayana döndürmesine neden olur. N atlanırsa, dönüş durumu işlev gövdesinde yürütülen son komutun durumudur.
... açık exit [n]
:
Kabuğun n durumuyla çıkmasına neden olur. N atlanırsa, çıkış durumu yürütülen son komutun durumudur. EXIT üzerinde bir tuzak, kabuk sona ermeden yürütülür.
DÜZENLE:
Soruyu düzenlemenize göre, çıkış kodlarıyla ilgili olarak, çıkış kodlarıyla return
ilgisi yoktur. Çıkış kodları işlevler için değil uygulamalar / komut dosyaları için tasarlanmıştır . Bu bakımdan, betiğin çıkış kodunu ayarlayan tek anahtar kelime ( $?
kabuk değişkeni kullanılarak çağıran program tarafından yakalanabilen ) exit
.
DÜZENLEME 2:
Yönlendiren exit
son ifadem bazı yorumlara neden oluyor. Farklılaştırmak için yapıldıreturn
ve exit
OP'nin anlaşılması için ve aslında, bir program / kabuk betiğinin herhangi bir noktasında exit
, betiği çağrı sürecine bir çıkış kodu ile bitirmenin tek yoludur.
Kabukta yürütülen her komut yerel bir "çıkış kodu" oluşturur: $?
bu koda değişken ve kullanılabilir if
, &&
ve koşullu diğer operatörler diğer komutları yürütün.
Bu çıkış kodları (ve $?
değişkenin değeri ) her komut yürütme tarafından sıfırlanır.
Bu arada, komut dosyası tarafından yürütülen son komutun çıkış kodu, çağıran işlem tarafından görüldüğü gibi komut dosyasının kendisinin çıkış kodu olarak kullanılır.
Son olarak, fonksiyonlar çağrıldığında çıkış kodlarına göre kabuk komutları olarak işlev görürler. Fonksiyonun çıkış kodu (fonksiyon içinde ) kullanılarak ayarlanır return
. Bu nedenle, bir işlevde return 0
çalıştırıldığında, işlev yürütmesi sonlanır ve 0 çıkış kodu verir.
func(){ return 50; };func;echo $?
50 yankıları. Yani $?
kabuk değişkeni ile sınırlı görünmüyor exit
.
$?
En son yürütülen ön plan boru hattının çıkış durumuna genişler." Bu çıkış, kabuktan bir çağrı şeklinde exit
(veya komut dosyasının sonuna vurarak) veya return
bir işlev içindeki çağrı şeklinde olabilir .
$?
Geçerli işlem / komut dosyasının , exit
bu komut dosyası tarafından yürütülen son komutla veya bunun sonucu ile sınırlıdır . Yani, son komut dosyası satırınız bu işleve çağrı ise ve bu işlev 50 döndürürse, evet, $?
sizi çağıran işleme ürettiğiniz 50'dir. Ancak, bununla ilgili olması gerekmez return
, çünkü bu geçerli komut dosyasıyla sınırlıdır. Yalnızca bu işlev çağrısı komut dosyasının son cümlesiyse döndürülür. exit
ancak, betiği her zaman bitirin ve $?
çağıran işlem için bu değeri döndürün .
return
çıkış kodları ile ilgisi yoktur." Deneme bana bir işlevin dönüş kodu ile bir komut dosyasının çıkış kodu arasında işlevsel bir fark olmadığını söylüyor.
return
geçerli işlevin kapsam dışına çıkmasına exit
neden olurken , komut dosyasının çağrıldığı noktada sona ermesine neden olur. İşte bunu açıklamaya yardımcı olacak örnek bir program:
#!/bin/bash
retfunc()
{
echo "this is retfunc()"
return 1
}
exitfunc()
{
echo "this is exitfunc()"
exit 1
}
retfunc
echo "We are still here"
exitfunc
echo "We will never see this"
$ ./test.sh
this is retfunc()
We are still here
this is exitfunc()
$?
.
echo fnord | while read x; do exitfunc; done; echo "still here"
"hala burada" yazdıracaktır. while
Bu senaryoda sadece alt kabuktan çıkılmış gibi görünüyor .
done || exit $?
ancak bu çirkin ve tam olarak eşdeğer değildir.
return
geçerli işlevin veya kaynaklı komut dosyasının kapsam dışına çıkmasına neden olacak '' .
Kimsenin soruyu tam olarak cevapladığını sanmıyorum çünkü ikisinin nasıl kullanıldığını tarif etmiyorlar. OK Bence çıkış komut dosyasının çağrıldığı yeri öldürdüğünü biliyoruz ve çıkış veya çıkış 0 veya çıkış 7 gibi bir durum atayabilirsiniz. Bu, başka bir komut dosyası vb. Tarafından çağrıldığında komut dosyasının nasıl durmaya zorlandığını belirlemek için kullanılabilir.
çağrıldığında döndür işlevi genellikle 1 veya 0 olmak üzere işlevin davranışını belirtmek için belirtilen değeri döndürür. Örneğin:
#!/bin/bash
isdirectory() {
if [ -d "$1" ]
then
return 0
else
return 1
fi
echo "you will not see anything after the return like this text"
}
şöyle kontrol et:
if isdirectory $1; then echo "is directory"; else echo "not a directory"; fi
ya da bunun gibi:
isdirectory || echo "not a directory"
Bu örnekte, test dizinin bulunup bulunmadığını göstermek için kullanılabilir. Geri dönüşten sonra hiçbir şeyin işlevde yürütülmeyeceğine dikkat edin. 0 doğrudur, ancak yanlış diğer prog dillerinden farklı olarak kabukta 1'dir.
İşlevler hakkında daha fazla bilgi için: http://www.linuxjournal.com/content/return-values-bash-functions
NOT: isdirectory işlevi yalnızca eğitim amaçlıdır. Gerçek bir senaryoda böyle bir seçeneği nasıl yaptığınız olmamalıdır.
test -d $1
aynı sonucu elde etmek için kullanın . Asla yapma if <check> return else return
. <check>
en azından bildiğim tüm dillerde tek başına aynı şeyi yapacaktır.
isdirectory() { [ -d "$1" ]; }
olmak için: burada sahip olduğunuzla aynı şekilde davranacaktır: Bir kabuk işlevinin varsayılan dönüş değeri, ister kodunun sonuna ulaşarak, ister return
argümanlarla değil, en son komut.
return
ifadenin davranışı hakkında konuşurken Mike Q'nun örneğinin stilini eleştiriyorlar . Örneğinin basit olduğu ve üretimde kullanılmayacağı doğrudur. Ama basit, bu yüzden görevini gayet iyi yerine getiriyor. Bunda yanlış bir şey yok.
Unutmayın, işlevler bir komut dosyasının içindedir ve normalde return ifadesi kullanılarak çağrıldıkları andan itibaren geri döner. Harici bir komut dosyasını çağırmak tamamen başka bir konudur ve komut dosyaları genellikle bir çıkış deyimi ile sona erer.
"BASH fonksiyonlarında return ve exit deyimleri arasında çıkış kodlarına göre" fark çok azdır. Her ikisi de kendi değerlerini değil, bir durum döndürür . Sıfır durumu başarıyı gösterirken, diğer tüm durumlar (1 ila 255) bir hata olduğunu gösterir. Return deyimi, komut dosyasının çağrıldığı yerden geri dönerken, çıkış deyimi tüm komut dosyasını karşılaşıldığı yerden sona erdirir.
return 0 # returns to where the function was called. $? contains 0 (success).
return 1 # returns to where the function was called. $? contains 1 (failure).
exit 0 # exits the script completely. $? contains 0 (success).
exit 1 # exits the script completely. $? contains 1 (failure).
İşleviniz herhangi bir döndürme ifadesi olmadan bitiyorsa, yürütülen son komutun durumu durum kodu olarak döndürülür (ve $?
).
Unutmayın, geri dönün ve çıkın 0 ile 255 arasında bir durum kodu verin, $?
. Bir durum koduna başka bir şey dolduramazsınız (örneğin, "cat" döndür); çalışmayacak. Ancak, bir komut dosyası durum kodlarını kullanarak 255 farklı hata nedenini geri verebilir.
Arama komut dosyasında yer alan değişkenleri ayarlayabilir veya sonuçların fonksiyonda yankılanması ve arama komut dosyasında komut değiştirme işlevinin kullanılması; ancak dönüş ve çıkışın amacı, C gibi bir programlama dilinde beklenebileceği gibi değerleri veya hesaplama sonuçlarını değil durum kodlarını iletmektir.
Bazen, .
veya kullanarak bir komut dosyası çalıştırırsınız source
.
. a.sh
Bir eklerseniz exit
içinde a.sh
, sadece senaryoyu sonlandırmak, ancak kabuk oturumu sona ermez.
Eğer bir eklerseniz return
içinde a.sh
, sadece dosyasını işlemeyi durdurur.
return: can only 'return' from a function or sourced script
, bu da genel bir komut dosyası için uygun değildir.
all
durumlar için uygun değildir . Bir alt kabuğu oluşturmak yerine betiği geçerli kabukta kullanmak .
veya source
çalıştırmak. Betiğin nasıl kullanılacağını bilmesi gerekir. Woe bunu tersine yapan kullanıcıya. Şahsen, ilk çalıştırmadan önce komut dosyalarını okumanızı tavsiye ederim.
trap
için işlev ERR EXIT
ve daha sonra ilk başarısız bir komutun çıkış kodu tasarrufu errCode=$?
ile senaryoyu (kaynaklı veya değil) çıkmak sonra ve return $errCode || exit $errCode
nerede ||
ben kaynaklı değildi çünkü döndüremez eğer" yollarla , bunun yerine çıkmanız yeterlidir ".
Basit bir ifadeyle (esas olarak kodlamadaki yeni başlayanlar için),
`return` : exits the function,
`exit()` : exits the program(called as process while running)
Ayrıca gözlemlediyseniz, bu çok basit ama ...,
`return` : is the keyword
`exit()` : is the function
exit
daha fazla veya daha az bir işlev değildir return
. Bunlar yerleşik komutlardır. Ayrılmış kelimeler bile değiller.
exit
mevcut süreci sonlandırmak ; çıkış kodu olsun veya olmasın, bunu bir program işlevinden daha çok bir sistem olarak düşünün. Kaynaklama yaparken exit
, kabuğu sonlandırır, ancak çalışırken sadece exit
komut dosyası olacaktır .
return
bir fonksiyondan çağrıdan sonra, bir dönüş kodu olsun veya olmasın talimatlara geri dönün. return
isteğe bağlıdır ve işlevin sonunda örtülüdür. return
yalnızca bir işlevin içinde kullanılabilir.
Ben kaynak yaparken exit
, kabuk öldürmeden bir fonksiyon içinde komut dosyası için kolay olmadığını eklemek istiyorum . Bence, bir örnek 'test' senaryosunda daha iyi
#!/bin/bash
function die(){
echo ${1:=Something terrible wrong happen}
#... clean your trash
exit 1
}
[ -f /whatever/ ] || die "whatever is not available"
# now we can proceed
echo "continue"
aşağıdakileri yapıyor:
user$ ./test
Whatever is not available
user$
test
-ve- kabuk kapanacak.
user$ . ./test
Whatever is not available
bir tek test
bitecek ve istem gösterilecektir.
Çözüm, potansiyel prosedürü (
ve)
#!/bin/bash
function die(){
echo $(1:=Something terrible wrong happen)
#... clean your trash
exit 1
}
( # added
[ -f /whatever/ ] || die "whatever is not available"
# now we can proceed
echo "continue"
) # added
şimdi, her iki durumda da sadece test
çıkacaktır.
(
ve )
koyar bir alt kabukta blok etkili un-yapıyor .
bir alt kabuk içindedir normalde test komut dosyası çalıştırmak sanki (kaynak) komutu. Komut dosyası ile çalıştırılmazsa .
veya source
etkili bir şekilde 2 alt kabukunuz varsa.
OP'nin sorusu: BASH işlevlerindeki return ve exit deyimleri arasındaki çıkış kodları arasındaki fark nedir?
Açıkçası, bazı açıklamalar gereklidir:
Yukarıdaki madde işareti listesinde, sırasıyla işlevler ve dönüş veya kabuklar ve çıkışlar hakkında ifadeler almak için her zaman ilk öğe veya her zaman ikinci öğe arasından "(x | y)" arasından seçim yapın.
Her ikisi de $ özel değişkeninin ortak kullanımını paylaştığı açık mı? değerleri, sona erdikten sonra yukarı doğru iletmek için.
* Şimdi $ özel yolları için? ayarlanabilir:
Bu $ dikkat çekmeye değer mi? aşağıdaki gibi bir alt kabukta çıkış çağrılarak bir değer atanabilir:
# (exit 259)
# echo $?
3
exit 259
atlaması durumunda 3
, son çıkış değeri tek bir bayt olduğu için yankılar . 259 % 256 = 3
Her şeyden önce, return
bir anahtar kelime ve exit
arkadaşım bir işlevdir.
Bununla birlikte, burada en basit açıklamalar var.
return
Bir işlevden bir değer döndürür.
exit
Geçerli kabuktan çıkar veya çıkar.
return
bir anahtar kelime iken bir işlevdir . Dönüş, çıkış kodlarından çok daha fazlasıdır, bu yüzden karşılaştırma adil değildir.
exit
de return
bash el kitabı tarafından "ayrılmış kelimeler" dediği gibi. İkisi de bash işlevi anlamında bir "işlev" değildir. Her ikisi de bash lingo'da yerleşik komutlardır . (Orada olup adlı bir C standart kütüphanesi işlevi exit()
ve C programlama dili ayrılmış sözcük bulunan return
, ancak bu onların semantik merakla benzer olmasına rağmen, bash komutlarıyla karıştırılmamalıdır.)
help <command>
Bir kabuk yerleşiminin ne yapacağına dair bilgi almak için kabuğunuzu yazın. Sizin durumunuzdahelp return
vehelp exit