Wykonywanie (exit 1);
jest najprostszym sposobem na uruchomienie ERR
pułapki. Spowoduje również natychmiastowe wyjście, jeśli set -e
jest aktywne. (Wywołanie warunku błędu wymaga wykonania komendy do niepowodzenia; exit
wartość błędu w podpowłoce powoduje awarię podpowłoki).
exit 1;
nie zrobi żadnej z tych rzeczy.
Więc {(exit 1); exit 1;}
może być stosowany do pierwszego produkować ERR
pułapkę, co może zrobić coś pożytecznego dla celów debugowania, a następnie wypowiedzieć skrypt ze wskazaniem błędów.
Ale nie o to chodzi w autoconf
plikach. autoconf
skrypty polegają na EXIT
pułapce w celu czyszczenia plików tymczasowych utworzonych podczas uruchamiania. Większość powłok, w tym bash
ustawia status na podstawie wartości podanej w exit
poleceniu przed wywołaniem EXIT
pułapki. To może pozwolić EXIT
pułapce na wykrycie, czy została wywołana na podstawie błędu, czy normalnego zakończenia, a także pozwala upewnić się, że status wyjścia jest poprawnie ustawiony na końcu operacji pułapki.
Jednak najwyraźniej niektóre pociski nie współpracują. Oto cytat z autoconf
instrukcji :
Niektóre skrypty powłoki, takie jak te generowane przez autoconf
, używają pułapki do czyszczenia przed wyjściem. Jeśli ostatnia komenda powłoki została zakończona z niezerowym statusem, pułapka kończy się również ze statusem niezerowym, aby wywołujący mógł stwierdzić, że wystąpił błąd.
Niestety, w niektórych powłokach, takich jak Solaris /bin/sh
, pułapka wyjścia ignoruje argument polecenia wyjścia. W tych powłokach pułapka nie może ustalić, czy została wywołana zwykłym wyjściem, czy wyjściem 1. Zamiast wywoływać wyjście bezpośrednio, użyj AC_MSG_ERROR
makra, które ma obejście tego problemu.
Obejściem tego problemu jest upewnienie się, że $?
ma status wyjścia przed wykonaniem exit
polecenia, aby na pewno miał tę wartość po wykonaniu EXIT
pułapki. I rzeczywiście, to AC_MSG_ERROR
makro wstawia ten ciekawy kod wraz z redundantnymi nawiasami klamrowymi.
false
zamiast(exit 1)
?false
nie pozwala ustawić kodu statusu i nie ma gwarancji, jaki zwróci niezerowy status. (2)false
zwykle nie jest wbudowany, więc wymaga procesu potomnego; w przeciwieństwie do większości pocisków można uniknąć odradzania się dziecka(exit 1)
.O ile mi wiadomo, nie ma w tym celu celu, nic nie można osiągnąć bezpośrednio, uruchamiając podpowłokę, a następnie natychmiast wychodząc.
Takie rzeczy są najprawdopodobniej efektem ubocznym automatycznego generowania kodu - w niektórych przypadkach mogą istnieć inne polecenia wykonywane w podpowłoce, jeśli ma
exit 1
to sens. Ostatecznie istnieje spora szansa, że kod generowania jest w jakiś sposób uproszczony, pozwalając mu wstawiać niektóre instrukcje, które w niektórych przypadkach nie mają żadnej funkcji, i generowanie „czystego kodu” za każdym razem jest bardziej złożone. Albo to, albo kod, który wygenerował powyższe, jest po prostu źle napisany :)Liberalne użycie
{...}
jest kolejnym przykładem tego, większość z nich jest redundantna, ale łatwiej jest napisać kod, który wstawia je w każdym przypadku (być może w niektórych chcesz przekierować wyjście / wejście bloku) niż rozróżniać te, w których nie są potrzebne i pomiń je.źródło
(exit 1)
to prosty, prawdopodobnie najprostszy sposób na uzyskanie określonego kodu wyjścia (w specjalnym przypadku 1 są oczywiście łatwiejsze sposoby). Ale nie jest to przyczyną w tym przypadku, ponieważ kod wyjścia nie jest badany.Celem umieszczenia
exit
podpowłoki może być niezakończenie skryptu (chociaż użycie wyjścia do wygenerowania określonego kodu wyjścia).źródło