Çıkış kodunu daha sonra kullanmak üzere kaydet


15

Bazı testler yapmak için küçük bir senaryom var.

javac *.java && java -ea Test
rm -f *.class

Şimdi bu sorun, betiği çalıştırdığınızda ./test, test başarısız olsa bile bir başarı çıkış kodu döndürecek olmasıdır rm -f *.class.

İstediğim şeyi yapmayı düşünebilmemin tek yolu bana çirkin geliyor:

javac *.java && java -ea Test
test_exit_code=$?
rm -f *.class
if [ "$test_exit_code" != 0 ] ; then false; fi

Ancak bu yaygın bir soruna benziyor - bir görev gerçekleştirin, temizleyin, ardından orijinal görevin çıkış kodunu döndürün.

Bunu yapmanın en deyimsel yolu nedir (genel olarak bash ya da genel olarak mermiler)?

Yanıtlar:


5

exitVe rmkomutlarını aşağıdaki evalgibi tek bir basit komuta sarabilirsiniz :

java ... && java ...
eval "rm -f *.class; exit $?"

Bu şekilde $?geçildiğinde değeri exit, koşmadan hemen önce atanan değerdir eval.


evalher zaman hayranların favorisidir.
mikeserv

23

Şununla giderdim:

javac *.java && java -ea Test
test_exit_code=$?
rm -f *.class
exit "$test_exit_code"

exitMevcut olduğunda neden zıplayın ?


Şunları kullanabilirsiniz trap:

trap 'last_error_code=$?' ERR

Örneğin:

$ trap 'last_error_code=$?' ERR
$ false
$ echo $?
1
$ echo $last_error_code $?
1 0

Ah, orijinalimden daha iyi katılıyorum. Ancak yine de çıkış kodunu bir değişkene açıkça saklamak zorunda kaldığım için tatmin edici hissetmemektedir. Bir çıkış kodunu 'itmenin' ve daha sonra tekrar 'pop' yapmanın bir yolu yok mu?
02:34

@ math4tots Güncellemeyi deneyin.
muru

Bu yüzden güncellemenizle last_error_code'u sıfıra başlatmak ve sonunda geri dönmek zorunda kaldım, böylece herhangi bir komut bir hata attığında sıfır olmayan çıkış kodum olurdu? Bu harika bir hile, ama iki satır hack senaryom için, sanırım @mikeserv'in cevabını tercih ediyorum.
math4tots

@ math4tots Her zaman yapabilirsiniz exit ${last_error_code:=0}.
muru

@avip ne için? Zaten tek tırnak içinde, bu yüzden değişken sadece tuzak çağrıldığında değerlendirilir.
muru

9

Bildiğim kadarıyla bash'ın try...finallydaha C benzeri bir programlama dilinden (eğer mevcut olsaydı muhtemelen isteyeceğiniz şey) bir bloğa sahip olması gereken şey şudur trap:

trap "rm -f *.class" EXIT
javac *.java && java -ea Test

Bu, komut dosyanızdan çıktığında "rm -f * .class" dosyasını yürütür. Yapmanız gereken daha karmaşık bir şey varsa, bunu bir işleve koyabilirsiniz:

cleanup() {
    ...
}
trap cleanup EXIT
javac *.java && java -ea Test

Eğer bu kadar eğimliyseniz, bunu kabaca try...catch...finallyC'deki bir blok gibi çalışan oldukça genel bir deyime dönüştürebilirsiniz.

(
  trap "catch_block; exit" ERR
  trap finally_block EXIT
  # contents of try goes here
)

Parantezlerin bir alt kabuğu sınırlandırdığına dikkat edin; bu yapı ile, komutun tamamı değil, bir komut başarısız olursa yalnızca alt kabuk çıkar. Alt kabukların biraz pahalı olduğunu unutmayın, bu yüzden çok fazla (yüzlerce) kullanmayın. Senaryonuza bağlı olarak kabuk efektleriyle aynı etkiyi daha verimli bir şekilde elde edebilirsiniz ve trap ... RETURNbu araştırmak size kalmış.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.