Differenza tra 2> & -, 2> / dev / null, | &, &> / dev / null e> / dev / null 2> & 1


192

Sto solo cercando la differenza tra

  • 2>&-
  • 2>/dev/null
  • |&
  • &>/dev/null
  • >/dev/null 2>&1

e la loro portabilità con non-Bourne shellscome tcsh, mkshecc


2
Si noti che, mentre mksh supporta la &>compatibilità GNU bash, si consiglia vivamente di non utilizzarlo, poiché l'analisi può interrompere la semantica degli script POSIX esistenti e mksh lo disabilita già in modalità POSIX.
mirabilos,

Ho visto anche ^ /dev/nullcosa fa?
Balupton,

Risposte:


241

Per lo sfondo:

  • un numero 1 = uscita standard (es. STDOUT)
  • un numero 2 = errore standard (cioè STDERR)
  • se un numero non viene specificato esplicitamente, il numero 1 viene assunto dalla shell (bash)

Innanzitutto affrontiamo la funzione di questi. Per riferimento, consultare la Guida avanzata di script Bash .

funzioni

2>&-

La forma generale di questo è M>&-, dove "M" è un numero descrittore di file. Ciò chiuderà l'output per qualsiasi descrittore di file a cui si fa riferimento, ovvero "M" .

2>/dev/null

La forma generale di questo è M>/dev/null, dove "M" è un numero descrittore di file. Ciò reindirizzerà il descrittore di file "M" a /dev/null.

2>&1

La forma generale di questo è M>&N, dove "M" e "N" sono numeri descrittori di file. Combina l'output dei descrittori di file "M" e "N" in un singolo flusso.

|&

Questa è solo un'abbreviazione per 2>&1 |. È stato aggiunto in Bash 4.

&>/dev/null

Questa è solo un'abbreviazione per >/dev/null 2>&1. Reindirizza il descrittore di file 2 (STDERR) e il descrittore 1 (STDOUT) su /dev/null.

>/dev/null

Questa è solo un'abbreviazione per 1>/dev/null. Reindirizza il descrittore di file 1 (STDOUT) su /dev/null.

Portabilità a non-bash, tcsh, mksh, ecc.

Non ho affrontato molto con altre shell al di fuori di cshe tcsh. La mia esperienza con quei 2 rispetto agli operatori di reindirizzamento di bash è che bash è superiore in questo senso. Vedi la pagina man di tcsh per maggiori dettagli.

Dei comandi che hai chiesto su nessuno sono direttamente supportati da csh / tcsh. Dovresti usare diverse sintassi per costruire funzioni simili.


Abbiamo un vincitore. Ma quindi non c'è differenza di prestazioni o qualcosa del genere con 2>&-vs 2>/dev/null(a parte il fatto che alcuni programmi scritti "male" non si annullano 2>&-correttamente)?
Det

3
Non ci dovrebbero essere differenze di prestazioni.
slm

5
&>era bashdall'inizio (e rompe la compatibilità con Bourne e POSIX in quanto significa qualcosa di diverso lì, anche se è improbabile che venga colpito). >&e |&provengono da (t)csh(ed è il loro unico modo per reindirizzare stderr). Erano presenti zshdall'inizio e sono stati aggiunti solo di recente bash. Vedi anche rcper operatori meglio progettati.
Stéphane Chazelas,

1
Aggiornamento: sul problema delle prestazioni, che è anche confermato qui: unix.stackexchange.com/questions/163955/…
Det

1
Ciao @slm, grazie per il contatto. Sono contento che il mio repository non sia cambiato (+2-2=0). Ora, per la parte dell'edizione, non modifico molto, ma in questo caso lo farei, perché chiarisce che i dati dopo l'operazione sarebbero a N. Ho letto la tua risposta, ed è molto bello sotto tutti gli aspetti. Proprio questa piccola ambiguità mi ha fatto pensare, ecco perché l'edizione. Ok, sentiti libero di aggiungerlo nuovamente o rifiutarlo, come vorrai. Spero di poter spiegare il punto. Continua così.
Dr Beco,

11

Questo è per reindirizzare STDERR e STDOUT:

  • 2>/dev/null

    Reindirizzare STDERR su / dev / null (impedire la visualizzazione sulla console)

  • |&

    Reindirizzare STDERR e STDOUT su STDIN del comando convogliato (cmd1 | & cmd2)

  • &>/dev/null

    Reindirizza STDERR e STDOUT a / dev / null (non viene visualizzato nulla sulla console)

  • >/dev/null

    Reindirizzare STDOUT su / dev / null (solo STDERR mostra sulla console)

  • 2>&-

    Serve per chiudere un descrittore di file usato con il reindirizzamento

Questi sono tutti metodi di reindirizzamento standard per le shell Bourne.


4
|&e non&>/dev/null sono portatili.
Chris Down,

4

Considera questo un addendum alla risposta selezionata. Potresti voler sapere quali moduli sono POSIX e quali no.

Sono coinvolti due moduli POSIX:

2.7.2 Reindirizzamento dell'output

I due formati generali per il reindirizzamento dell'output sono:

[N]> parola

[N]> | parola

dove n opzionale rappresenta il numero del descrittore di file. Se il numero viene omesso, il reindirizzamento deve fare riferimento all'output standard (descrittore di file 1).

Il reindirizzamento dell'output utilizzando il formato '>' non avrà esito positivo se è impostata l'opzione noclobber (vedere la descrizione di set -C) e il file denominato dall'espansione di word esiste ed è un file normale. Altrimenti, reindirizzamento utilizzando '>' o "> |" i formati causano la creazione e l'apertura del file il cui nome deriva dall'espansione della parola per l'output sul descrittore di file designato o l'output standard se non ne viene specificato nessuno. Se il file non esiste, deve essere creato; in caso contrario, verrà troncato per essere un file vuoto dopo essere stato aperto.

-

2.7.6 Duplicazione di un descrittore di file di output

L'operatore di reindirizzamento:

[N]> & parola

deve duplicare un descrittore di file di output da un altro o chiuderne uno. Se la parola restituisce una o più cifre, il descrittore di file indicato da n o l'output standard se n non è specificato, deve essere una copia del descrittore di file indicato da parola; se le cifre in parola non rappresentano un descrittore di file già aperto per l'output, si verificherà un errore di reindirizzamento; vedi Conseguenze degli errori Shell. Se la parola restituisce '-', il descrittore di file n o l'output standard se n non è specificato, viene chiuso. I tentativi di chiudere un descrittore di file non aperto non devono costituire un errore. Se la parola restituisce qualcos'altro, il comportamento non è specificato.

Perciò:

Function      POSIX-compat    POSIX 
2>&-          Yes             close 
2>/dev/null   Yes             redir
2>&1          Yes             dup 
|&            No              
&>/dev/null   No
>/dev/null    Yes             redir
>&/dev/null   ?               ?dup

L'ultima riga non è nella domanda originale, ma funziona senza lamentarsi in bash. (Funziona anche con / dev / tty sostituito a / dev / null).


1
Voglio sempre saperne di più.
Det
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.