2011-03-15 37 views
31

Bash kodumda birçok çıkış noktası var. Bazı Çıkışta işi temizlemek yapmak gerekir, bu yüzden böyle çıkış için bir geri arama eklemek için tuzak kullandı:Bash komut dosyasında çıkış kodu nasıl yazılır

trap "mycleanup" EXIT 

sorun farklı çıkış kodları oradayız, ben temizliğe gelen yapmak gerekir. Mycleanup'da çıkış kodunu alabilir miyim?

+0

trap 'foo' EXIT veya 'foo' CHLD? –

cevap

31

Çıkış kodunu almak için $?'u kullanabilirsiniz.

+1

evet, doğru. Teşekkürler! – Dagang

+2

@Todd: Bazen $ BASH_COMMAND ve $ BASH_LINENO değişkenleri de kullanışlı oluyor. –

+4

@Todd, @bmk: Unutmayın ki * herhangi * komutu çalıştırılan $ değerini değiştirir; örneğin, myCmdIWantToTest; echo $? ; myRC = $? ; ... şimdi myRC echo $ 'gerçeği? cmd çağrılmakta. MyCmdIWantToTest 'false' 'den çıkarsa, bu değer kaybolur. $ Kaydetmek için en iyisi? benzersiz olarak adlandırılmış ayrı bir var. ExitCode kullanarak = $? evrensel olarak, başka bir cmd'nin exitCode'unu (veya bir alt kabuktan (script) daha büyük olasılıkla) devralırken kolayca kurtarabilirsiniz. Ayrıca, sınamanın bir parçası olarak test çıkış kodunun tamam olduğunu unutmayın; sonra ; ... fi. MyCmdIWantToTest gibi; sonra eko çalıştı; başka yankı başarısız oldu; fi – shellter

25

Kabul edilen cevap temelde doğru, sadece bazı şeyleri açıklığa kavuşturmak istiyorum.

Aşağıdaki örnek

iyi çalışıyor:

#!/bin/bash 

cleanup() { 
    rv=$? 
    rm -rf "$tmpdir" 
    exit $rv 
} 

tmpdir="$(mktemp)" 
trap "cleanup" INT TERM EXIT 
# Do things... 

Ama bir fonksiyonu olmadan, temizleme inline yapıyor eğer daha dikkatli olmak zorunda. Örneğin bu çalışmaz:

trap "rv=\$?; rm -rf $tmpdir; exit \$rv" INT TERM EXIT 
Ayrıca o değerlendirilecektir alacak gibi $tmpdir kaçmak isteyebilirsiniz

tuzak hattı:

trap "rv=$?; rm -rf $tmpdir; exit $rv" INT TERM EXIT 

Bunun yerine $rv ve $? değişkenleri kaçmak zorunda çalıştırılır ve tmpdir değeri daha sonra değişirse, beklenen davranışı vermez.

Düzenleme: Bash komut dosyalarınızı kontrol etmek ve bunun gibi sorunlardan haberdar olmak için shellcheck'u kullanın.

2

ben ... diğer sinyalleri

Örnek tuzak test script için tuzak ayrı ÇIKIŞ tuzak daha iyidir buldum

umask 77 
tmpfile=`tmpfile.$$` 
trap 'rm -f "$tmpfile"' EXIT 
trap 'exit 2' HUP INT QUIT TERM 

touch $tmpfile 
read -r input 

exit 10 

geçici dosya temizlenir. 10 dosya çıkış değeri korunur! Kesmeler, çıkış değerinin 2

çıkmasına neden olur. Bir EXIT tuzağında "çıkış" kullanmadığınız sürece, korunan orijinal çıkış değeri ile çıkılır.

ASIDE: EXIT tuzağındaki alıntılara dikkat edin. Bu, betiğin ömrü boyunca hangi dosyanın temizlenmesinin gerektiğini değiştirmeme izin veriyor. Sıklıkla $ tmpfile varables varlığı için bir test de dahil ediyorum, bu yüzden betiğin başlangıcında ayarlamanıza bile gerek yok.

İlgili konular