Come potrei ricordare come usare il reindirizzamento?


40

io so cosa

  program > /dev/null 2>&1 

lo fa. Reindirizza l'output /dev/nulle 2>&1significa reindirizzare l'output di errore nello stesso punto in cui viene inviato l'output.

Il mio problema è che devo sempre cercarlo su Google perché non me lo ricordo mai.

Quindi, cerco &2>1, 1>2&, 1>&2... provo ogni combinazione fino a quando ho google ...

Qual è il trucco per ricordarlo facilmente?


Ho lo stesso problema, quindi lo faccio nel modo "lungo" - reindirizzare entrambi program 1> /dev/null 2>/dev/null. Alcune volte però è necessario mescolare stdoute stderrinsieme per vedere cosa sta realmente succedendo, come l'output di un processo di compilazione complesso che viene reindirizzato a un file. In tal caso,
finisco per cercare

Risposte:


20

L'output è migliore dell'errore, quindi viene prima (1 vs 2).

>è una scorciatoia per "va a". A sinistra è ciò che voglio inviare e a destra è dove voglio inviarlo. Poiché "dove" è (quasi) sempre un file, qualcosa del genere

program > /dev/null 2>1

reindirizzerebbe a un file denominato 1. Pertanto, la e commerciale (&)modifica il file nel descrittore di file.

Sfortunatamente, non mi sono mai imbattuto né sviluppato il mio mnemonico, ma quando ho iniziato a studiare * nix, ho trovato questo modo logico di funzionare bene. Dopo alcuni passaggi, diventa una seconda natura.


La tua prima frase non ha senso per me. stdoutè il descrittore di file 1, stderrè 2. Quindi, "errore" precede "output".
Warren Young,

Quella frase è un mnemonico per ricordare quale descrittore di file stdoute stderrriferirsi.
gvkv,

Va bene, ma sembra ancora confuso, poiché la domanda originale riguarda il tentativo di ricordare l'ordine dei personaggi nell'incantesimo "2> & 1".
Warren Young,

9

Un trucco è solo per ricordare che 1 = output standard, 2 = errore standard. Così:

2>&1= il flusso di errori standard passa al flusso di output standard.
1>&2= viceversa.

Se hai mai programmato in un linguaggio di tipo C, è facile ricordare la e commerciale ( &). Ho scelto di pensarlo come riferito all '"indirizzo del" descrittore di file esistente, in modo da non modificare il file stesso o crearne uno nuovo.


7

Vedere &come un nodo potrebbe aiutare: pensa a cosa vuoi fare come prendere l'output di 2, quindi 2>, e legarlo insieme a 1, quindi2>&1


2
Ho appena memorizzato la frase "due fuori e uno". Che il tuo mnemonico sia una frase o un nodo, averne uno ti aiuterà davvero.
Tim Kennedy,

5

In realtà, dipende da quale shell stai usando. Bash di solito è molto indulgente e puoi semplicemente fare:

program &> file

5

Consideriamo queste tre opzioni:

program  2>1
program  2>1& 
program  2>&1

Il primo invia stderr al nome di un file "1": dopotutto, bash si aspetta di reindirizzare a un file.

Il secondo reindirizza anche allo stesso file ma viene eseguito programin background: questo &dovrebbe significare un trailing .

Ciò lascia la terza possibilità come l'unica che ha senso nell'universo bash per il reindirizzamento a un handle di file.

Come ricordare quale è quale tra 0, 1, 2? Pensa a far funzionare un computer dalla console. Innanzitutto, devi digitare qualcosa (0 = stdin). Quindi, vedi l'output (1 = stdout). Infine e solo se qualcosa va storto, vedi stderr (2).


1

Disegnalo sullo sfondo.

Ora, sul serio, questa e altre cose di base che ho continuato a dimenticare, quindi ho aggiunto un rapido menu di suggerimenti a un'app che ho sviluppato e che uso quotidianamente. Potresti provare o usare qualcosa come gnote per tenere una nota.


1

Per quanto riguarda la shell bash, trovo che il modo migliore per ricordare sia capire cosa sta succedendo.
Se tutto ciò che vuoi fare è ricordare come ottenere il comando corretto, potresti provare

program > /results 2> /results

È bello e ovvio cosa sta succedendo e facile da ricordare. vale a dire

  • 1 STDOUT lo farà /results
  • 2Anche STDERR sta andando direttamente a/results

il problema è che questo non funziona come ci si aspetterebbe. considerare quanto segue:

file: /tmp/poem.txt

the quick brown fox jumped over the lazy dog

e esegui il comando

grep "brown" /tmp/poem.txt NOT_A_FILE > /tmp/results 2> /tmp/results

poi

$ cat /tmp/results
grep: NOT_A_FILE: No such file or directory
 lazy dog

cos'è successo qua?
La mia comprensione è bash impostare il reindirizzamento che punta lo STDERR direttamente al file /tmp/resultse per la natura del >quale fa 2 cose

  1. normalmente crea un nuovo file - in questo caso l'opportunità è passata poiché bash ha superato questa routine al momento della generazione dell'output.
  2. inserire direttamente all'inizio del file. e non aggiungere come >>fa.

Quindi, in questo caso STDERR, si inserisce direttamente all'inizio /tmp/resultsdell'override dell'output di STDOUT.
Nota: se hai usato>> accedeva, probabilmente si poteva cavarsela con questa sintassi.
Tuttavia, per risolvere il problema è necessario, non reindirizzare STDERR direttamente al file, ma piuttosto unire l'output di STDERR nel flusso STDOUT, in modo da non ottenere una collisione.
L'utilizzo dell'operatore 2>&1operatore consente di ottenere questo risultato

grep "brown" poem.txt NOT_A_FILE > /tmp/results 2>&1

Il &permette bash da distinguere da un file chiamato 1 e il 1descrittore di file.
Per me l'affermazione 2>&1stessa spiega esattamente cosa sta succedendo - STDERR viene reindirizzato allo STDOUT stesso - e finisce solo /tmp/resultsperché è lì che viene indicato STDOUT (quasi come un effetto collaterale).
Contrariamente a quanto sostengono molte guide, ovvero che 2>&1invia STDERR a qualsiasi punto di STDOUT. Se ciò fosse vero, avresti comunque il problema di sovrascrittura.

Per ulteriori informazioni, vedere - http://mywiki.wooledge.org/BashGuide/InputAndOutput#File_Redirection

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.