GNU/Linux >> Znalost Linux >  >> Linux

Existují v Linuxu nějaké standardní kódy ukončení?

'1' :Přehled obecných chyb

2' :Zneužití zabudovaných shellů (podle dokumentace Bash)

126 :Vyvolaný příkaz nelze provést

'127' :"příkaz nenalezen"

'128' :Neplatný argument pro ukončení

'128+n' :Signál závažné chyby "n"

'130' :Skript ukončen klávesou Ctrl + C

255 :Stav ukončení mimo rozsah

Tohle je pro Bashe. Pro jiné aplikace však existují různé ukončovací kódy.


Část 1:Průvodce pokročilého skriptování Bash

Jako vždy má Advanced Bash Scripting Guide skvělé informace:(Toto bylo propojeno v jiné odpovědi, ale s nekanonickou adresou URL.)

1: Záchytka za obecné chyby
2: Zneužití vestavěných shellů (podle dokumentace Bash)
126: Vyvolaný příkaz nelze provést
127: "příkaz nenalezen"
128: Neplatný argument pro ukončení
128+n: Fatální chybový signál "n"
255: Stav ukončení mimo rozsah (ukončení trvá pouze celé číslo v rozsahu 0–255)

Část 2:sysexits.h

ABSG odkazuje na sysexits.h .

V systému Linux:

$ find /usr -name sysexits.h
/usr/include/sysexits.h
$ cat /usr/include/sysexits.h

/*
 * Copyright (c) 1987, 1993
 *  The Regents of the University of California.  All rights reserved.

 (A whole bunch of text left out.)

#define EX_OK           0       /* successful termination */
#define EX__BASE        64      /* base value for error messages */
#define EX_USAGE        64      /* command line usage error */
#define EX_DATAERR      65      /* data format error */
#define EX_NOINPUT      66      /* cannot open input */    
#define EX_NOUSER       67      /* addressee unknown */    
#define EX_NOHOST       68      /* host name unknown */
#define EX_UNAVAILABLE  69      /* service unavailable */
#define EX_SOFTWARE     70      /* internal software error */
#define EX_OSERR        71      /* system error (e.g., can't fork) */
#define EX_OSFILE       72      /* critical OS file missing */
#define EX_CANTCREAT    73      /* can't create (user) output file */
#define EX_IOERR        74      /* input/output error */
#define EX_TEMPFAIL     75      /* temp failure; user is invited to retry */
#define EX_PROTOCOL     76      /* remote error in protocol */
#define EX_NOPERM       77      /* permission denied */
#define EX_CONFIG       78      /* configuration error */

#define EX__MAX 78      /* maximum listed value */

8 bitů návratového kódu a 8 bitů čísla vražedného signálu je smícháno do jediné hodnoty při návratu z wait(2) &co..

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>

int main() {
    int status;

    pid_t child = fork();
    if (child <= 0)
        exit(42);
    waitpid(child, &status, 0);
    if (WIFEXITED(status))
        printf("first child exited with %u\n", WEXITSTATUS(status));
    /* prints: "first child exited with 42" */

    child = fork();
    if (child <= 0)
        kill(getpid(), SIGSEGV);
    waitpid(child, &status, 0);
    if (WIFSIGNALED(status))
        printf("second child died with %u\n", WTERMSIG(status));
    /* prints: "second child died with 11" */
}

Jak určujete výstupní stav? Shell tradičně ukládá pouze 8bitový návratový kód, ale nastavuje horní bit, pokud byl proces abnormálně ukončen.

$ sh -c 'exit 42'; echo $?
42
$ sh -c 'kill -SEGV $$'; echo $?
Segmentation fault
139
$ expr 139 - 128
11

Pokud vidíte něco jiného než toto, pak má program pravděpodobně SIGSEGV signál handler, který pak volá exit normálně, takže ve skutečnosti není zabit signálem. (Programy se mohou rozhodnout zpracovat jakékoli signály kromě SIGKILL a SIGSTOP .)


Žádná ze starších odpovědí nepopisuje správně výstupní stav 2. Na rozdíl od toho, co tvrdí, stav 2 je to, co vaše nástroje příkazového řádku skutečně vrátí, když jsou volány nesprávně. (Ano, odpověď může být devět let stará, mít stovky hlasů pro a přesto může být špatná.)

Zde je skutečná, dlouhodobá konvence stavu odchodu pro normální ukončení, tj. ne signálem:

  • Stav ukončení 0:úspěch
  • Stav ukončení 1:"selhání", jak je definováno programem
  • Stav ukončení 2:Chyba použití příkazového řádku

Například diff vrátí 0, pokud jsou soubory, které porovnává, identické, a 1, pokud se liší. Podle dlouholeté konvence vrací unixové programy stav ukončení 2, když jsou volány nesprávně (neznámé možnosti, nesprávný počet argumentů atd.) Například diff -N , grep -Y nebo diff a b c výsledkem všech bude $? je nastaven na 2. Toto je a bylo praxí od počátků Unixu v 70. letech 20. století.

Přijatá odpověď vysvětluje, co se stane, když je příkaz ukončen signálem. Stručně řečeno, ukončení kvůli nezachycenému signálu má za následek stav ukončení 128+[<signal number> . Např. ukončení pomocí SIGINT (signál 2) má za následek návratový stav 130.

Poznámky

  1. Několik odpovědí definuje stav ukončení 2 jako „Zneužití zabudovaných bash“. To platí pouze při bash (nebo bash skript) se ukončí se stavem 2. Považujte to za zvláštní případ chyby nesprávného použití.

  2. V sysexits.h , zmíněný v nejoblíbenější odpovědi, stav ukončení EX_USAGE ("chyba použití příkazového řádku") je definována jako 64. To však neodráží realitu:žádné mi nejsou známy běžná unixová utilita, která vrací 64 při nesprávném vyvolání (příklady vítány). Pečlivé čtení zdrojového kódu odhalí, že sysexits.h je aspirační, spíše než odraz skutečného použití:

     *    This include file attempts to categorize possible error
     *    exit statuses for system programs, notably delivermail
     *    and the Berkeley network.
    
     *    Error numbers begin at EX__BASE [64] to reduce the possibility of 
     *    clashing with oth­er exit statuses that random programs may 
     *    already return. 
    

    Jinými slovy, tyto definice neodrážejí běžnou praxi v té době (1993), ale byly s ní záměrně neslučitelné. Více je škoda.


Linux
  1. Může Grep vrátit pravdu/nepravdu nebo existují alternativní metody?

  2. Linux – Jak zjistit, zda jsou ve složce soubory, a podle toho ukončit (v Ksh)?

  3. Linux – minimální a maximální hodnoty výstupních kódů v Linuxu?

  1. Linux – Existují nějaké nástroje Gui pro Linux, které nepoužívají X11?

  2. Linux – Jsou různá jádra Linux/unix zaměnitelná?

  3. Existuje STDCALL v Linuxu?

  1. Existuje nějaký způsob, jak získat 64bitový time_t v 32bitových programech v Linuxu?

  2. Existují nějaké moderní distribuce Linuxu, které stále podporují /dev/audio?

  3. Existuje nějaký způsob, jak zablokovat LD_PRELOAD a LD_LIBRARY_PATH na Linuxu?