GNU/Linux >> Znalost Linux >  >> Linux

Gnu Awk Errno není nastaveno při selhání příkazu?

Zkoušel jsem spustit několik příkazů pomocí getline() funkce GNU awk a vytiskněte číslo chyby (errno ) vrácená hodnota. Ale pro jednoduché případy selhání neexistujícího adresáře/souboru se zdá, že proměnná není naplněna.

awk 'BEGIN {
        cmd = "ls -lrth /non/existing/path"
        while ( ( cmd | getline result ) > 0 ) {
            print result
        }
        close(cmd); print ENVIRON["ERRNO"]
}'

Když výše uvedené vyhodí chybový řetězec z ls , print příkaz nevytváří platné číslo chyby. Z manuálové stránky jsem také zkusil použít PROCINFO["errno"] a PROCINFO["ERRNO"] která nefungovala. Také jsem to zkusil vytisknout před zavřením deskriptoru souboru, což také nefungovalo. Je špatné očekávat ENOENT v tomto případě?

Přijatá odpověď:

Pomocí getline nemůžete získat číslo chyby . Ve vašem příkazu je výstup z ls , nikoli print result .

Ve tvaru cmd | getline result , cmd je spuštěn, pak je jeho výstup přesměrován do getline . Vrací 1 pokud dostane výstup, pokud EOF, -1 na selhání. Problém je v tom, že selhání je způsobeno spuštěním getline samotný, nikoli návratový kód cmd . Příklad:

awk 'BEGIN {
while ( ( getline result < "/etc/shadow") > 0 ) {
            print result
        }
        print "XXX: ", ERRNO
}'
XXX:  Permission denied

Uvidíte, že /etc/shadow nelze přečíst, takže getline se nespustí a hlásí chybu v ERRNO proměnná.

Pamatujte, že GNU awk vrátí cmd stav, pokud není v režimu posix, takže můžete:

awk 'BEGIN {
    cmd = "ls -lrth /non/existing/path"
    while ( ( cmd | getline result ) > 0 ) {
        print result
    }
    status=close(cmd);
    if (status != 0) {
        code=and(rshift(status, 8),0xFF)
        printf("Exit status: %d, exit code: %d\n", status, code)
    }
}'
ls: cannot access '/non/existing/path': No such file or directory
Exit status: 512, exit code: 2

V režimu POSIX nezískáte stav ukončení:

POSXILY_CORRECT=1 awk 'BEGIN {
    cmd = "ls -lrth /non/existing/path"
    while ( ( cmd | getline result ) > 0 ) {
        print result
    }
    status=close(cmd);
    if (status != 0) {
        code=and(rshift(status, 8),0xFF)
        printf("Exit status: %d, exit code: %d\n", status, code)
    }
}'
ls: cannot access '/non/existing/path': No such file or directory

Linux
  1. Náhrada příkazů:rozdělení na nový řádek, ale ne mezera?

  2. ifrename:příkaz nenalezen

  3. nc:příkaz nenalezen

  1. rm:příkaz nenalezen

  2. mv:příkaz nenalezen

  3. ln:příkaz nenalezen

  1. Subscription-manager:příkaz nenalezen

  2. awk:příkaz nenalezen

  3. Jak získat stav ukončení příkazu shellu používaného v GNU Makefile?