Mam więc mały skrypt do uruchamiania niektórych testów.
javac *.java && java -ea Test
rm -f *.class
Problem polega na tym, że po uruchomieniu skryptu ./test
zwróci kod zakończenia powodzenia, nawet jeśli test się nie powiedzie, ponieważ się rm -f *.class
powiedzie.
Jedyny sposób, w jaki mogłem pomyśleć o zrobieniu tego, co chcę, jest dla mnie brzydki:
javac *.java && java -ea Test
test_exit_code=$?
rm -f *.class
if [ "$test_exit_code" != 0 ] ; then false; fi
Ale wydaje się, że jest to typowy problem - wykonaj zadanie, posprzątaj, a następnie zwróć kod wyjścia oryginalnego zadania.
Jaki jest najbardziej idiomatyczny sposób na zrobienie tego (w bashu lub ogólnie w powłokach)?
bash
shell
exit-status
math4tots
źródło
źródło
eval
jest zawsze ulubieńcem fanów.Poszedłbym z:
Po co skakać, kiedy
exit
jest dostępny?Możesz użyć
trap
:Na przykład:
źródło
exit ${last_error_code:=0}
.O ile wiem, najbliższą rzeczą, którą bash ma do
try...finally
bloku z języka programowania podobnego do C (co prawdopodobnie byś chciał, gdyby był dostępny) jesttrap
konstrukcja, która działa w następujący sposób:Spowoduje to wykonanie polecenia „rm -f * .class” po zakończeniu skryptu. Jeśli masz coś bardziej skomplikowanego do zrobienia, możesz umieścić to w funkcji:
Jeśli masz takie skłonności, możesz zmienić to w dość ogólny idiom, który działa mniej więcej tak jak
try...catch...finally
blok w C. Coś takiego:Zauważ, że nawiasy ograniczają podpowłokę; w tej konstrukcji tylko podpowłoka kończy działanie, jeśli polecenie się nie powiedzie, a nie cały skrypt. Pamiętaj, że podpowłoki są nieco drogie obliczeniowo, więc nie używaj ich zbyt wielu (setek). W zależności od skryptu możesz osiągnąć ten sam efekt bardziej efektywnie dzięki funkcjom powłoki i
trap ... RETURN
, ale to zależy od ciebie.źródło