Stato di uscita diverso da zero per uscita pulita


15

È accettabile restituire un codice di uscita diverso da zero se il programma in questione è stato eseguito correttamente? Ad esempio, supponiamo di avere un semplice programma che (solo) fa quanto segue:

Il programma accetta N argomenti. Restituisce un codice di uscita di min (N, 255). Si noti che qualsiasi N è valida per il programma.

Un programma più realistico potrebbe restituire codici diversi per programmi eseguiti correttamente che indicano cose diverse. Questi programmi dovrebbero invece scrivere queste informazioni su uno stream, ad esempio su stdout?

Risposte:


24

Dipende dall'ambiente, ma direi che è uno stile scadente.

I sistemi simili a Unix hanno una forte convenzione secondo cui uno stato di uscita pari a 0 indica il successo e qualsiasi stato di uscita diverso da zero indica un fallimento. Alcuni programmi, ma non tutti, distinguono tra diversi tipi di guasti con codici di uscita diversi da zero; ad esempio, in grepgenere restituisce 0 se il modello è stato trovato, 1 se non lo è stato e 2 (o più) se si è verificato un errore come un file mancante.

Questa convenzione è praticamente cablata nelle shell Unix. Ad esempio, in sh, bashe altre shell tipo Bourne, l' ifistruzione considera uno stato di uscita 0 come successo / vero e uno stato di uscita diverso da zero come fallimento / falso:

if your-command
then
    echo ok
else
    echo FAILURE
fi

Credo che le convenzioni in MS Windows siano simili.

Ora non c'è nulla che ti impedisca di scrivere il tuo programma che utilizza codici di uscita non convenzionali, soprattutto se nient'altro interagirà con esso, ma tieni presente che stai violando una convenzione consolidata e potrebbe tornare e morderti in seguito .

Il modo normale per un programma di restituire questo tipo di informazioni è di stamparlo su stdout:

status = $(your-command)
echo Result is $status

7
+1 per spiegare la convenzione, quell'approccio avrebbe spezzato la maggior parte dei miei script di shell se l'avessi messo da set -equalche parte.
Benjamin Bannier,

Analogamente grep, diffrestituisce 1 quando vengono rilevate differenze; e> 1 se si è verificato un errore.
7heo.tk,

6

Dipende da ciò che il tuo ambiente si aspetta.

Il mio preferito per la stranezza, da Wikipedia :

In OpenVMS, il successo è indicato da valori dispari e il fallimento da valori pari. Il valore è un numero intero a 32 bit con sottocampi: bit di controllo, numero di funzione, numero di messaggio e gravità. I valori di gravità sono divisi tra successo (Successo, Informativo) e fallimento (Avvertenza, Errore, Fatale).


4

Penso che ci sia un precedente se il codice di uscita sta restituendo al chiamante informazioni significative e pertinenti e la definizione di successo non è realmente binaria. Il precedente a cui sto pensando è il robocopy che restituisce una serie di cose diverse a seconda di ciò che è successo .

Aggiungo che finiamo sempre per avere un po 'di debug a causa di questo - la maggior parte delle utility presume il codice di uscita 0 == successo quindi fatti impazzire quando robocopy restituisce 1 perché ha copiato cose non zero perché non ha copiato cose ma non ha fatto t ottenere un errore neanche.


2

non restituire 0 per una corretta esecuzione è una cattiva idea, perché può creare confusione per coloro che eseguono il programma. Che cosa succede se alcuni eseguono il tuo programma 100+ volte con input diversi e volessero sapere quanti falliscono o completano con successo, avere un singolo valore di successo rende molto più facile individuare le differenze piuttosto che avere molti valori diversi.

Se hai un programma che ha più percorsi di ritorno di successo che possono significare tutti cose diverse, direi che è un segno che il tuo programma è mal progettato.


2

Conosco un caso che ritengo accettabile. Conosco un framework di test che esce con il numero totale di fallimenti di test. Quindi, ad esempio, se il test runner si completa senza test falliti, esce con zero. Se un test ha esito negativo, anche se il test runner stesso ha funzionato correttamente, esce con uno 1. Se due falliscono restituisce 2, ecc. Questo porta a 250, che significa "250 o più errori di test".

Utilizza codici di uscita> 250 per indicare uscite anomale.

Mentre questo viola la convenzione, funziona bene in pratica.


3
Non credo che questo non violare convenzione - il test ha successo se non ci sono errori; qualsiasi codice di risultato diverso da zero indica test non riusciti.
Bevan,

1
Questo significa "uscire con uno stato di errore per indicare più di 0 errori" e sebbene possa violare l'esatta semantica comune dello stato di uscita, certamente non viola il più grande "0 è OK, tutto ciò che è maggiore di 0 è un errore" convenzione .
Vatine,

2

Dipende davvero da cosa stai cercando di comunicare con il codice. DB2, ad esempio, restituisce 100 se non sono stati trovati dati, vari altri valori positivi per gli avvisi e valori negativi per gli errori. Oracle fa qualcosa di simile.

Quindi, se ci sono diversi stati di successo, può valere la pena utilizzare valori di ritorno variabili.


2

Un buon esempio: man sa-update (spamassassin)

CODICI DI USCITA

  • Un codice di uscita pari a 0 indica che era disponibile un aggiornamento ed è stato scaricato e installato correttamente se --checkonly non è stato specificato.
  • Un codice di uscita pari a 1 indica che non erano disponibili nuovi aggiornamenti.
  • Un codice di uscita di 2 significa ...

In questo caso, l'uscita 1 è semplicemente un codice informativo. Tuttavia, se avessi scritto il codice, non avrei scelto 1 dal momento che di solito manca la corrente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.