GNU/Linux >> Linux Esercitazione >  >> Linux

Reindirizzare tutti i comandi successivi Stderr usando Exec?

Ho un file bash di cui ho bisogno per reindirizzare tutto l'output su un file, registro di debug e sul terminale. Devo reindirizzare sia stdout che stderr al debug e registrarlo per tutti i comandi nello script.

Non voglio aggiungere 2>&1 | tee -a $DEBUG per ogni singolo comando nel file. Potrei vivere con | tee -a $DEBUG .

Ricordo che c'era un modo per farlo con qualcosa come exec 2>&1 .

Attualmente sto usando qualcosa come il seguente:

#!/bin/bash
DEBUGLOG=/tmp/debug
exec 2>&1
somecommand | tee -a $DEBUGLOG
somecommand2 | tee -a $DEBUGLOG
somecommand3 | tee -a $DEBUGLOG

ma non funziona. Qualcuno ha una soluzione/può spiegare la causa?

Risposta accettata:

Per quanto riguarda una soluzione per reindirizzare molti comandi contemporaneamente:

#!/bin/bash
{
    somecommand 
    somecommand2
    somecommand3
} 2>&1 | tee -a $DEBUGLOG

Perché la tua soluzione originale non funziona:exec 2>&1 reindirizzerà l'output dell'errore standard allo standard output della tua shell, che, se esegui lo script dalla console, sarà la tua console. il reindirizzamento della pipe sui comandi reindirizzerà solo l'output standard del comando.

Dal punto di vista di somecommand , il suo output standard va in una pipe collegata a tee e l'errore standard va nello stesso file/pseudofile dell'errore standard della shell, che reindirizzerai allo standard output della shell, che sarà la console se esegui il tuo programma dalla console.

L'unico vero modo per spiegarlo è vedere cosa succede davvero:

L'ambiente originale della tua shell potrebbe assomigliare a questo se lo esegui dal terminale:

stdin -> /dev/pts/42
stdout -> /dev/pts/42
stderr -> /dev/pts/42

Dopo aver reindirizzato l'errore standard nell'output standard (exec 2>&1 ), tu... praticamente non cambi nulla. Ma se reindirizzi l'output standard dello script su un file, ti ritroverai con un ambiente come questo:

stdin -> /dev/pts/42
stdout -> /your/file
stderr -> /dev/pts/42

Quindi reindirizzare l'errore standard della shell nello standard output finirebbe in questo modo:

stdin -> /dev/pts/42
stdout -> /your/file
stderr -> /your/file

L'esecuzione di un comando erediterà questo ambiente. Se esegui un comando e lo reindirizza al tee, l'ambiente del comando sarebbe:

stdin -> /dev/pts/42
stdout -> pipe:[4242]
stderr -> /your/file

Quindi l'errore standard del tuo comando va ancora in ciò che la shell usa come errore standard.

Correlati:${!FOO} e zsh?

Puoi effettivamente vedere l'ambiente di un comando guardando in /proc/[pid]/fd :usa ls -l per elencare anche il contenuto del collegamento simbolico. Il il file qui è l'input standard, 1 è l'output standard e 2 è un errore standard. Se il comando apre più file (e la maggior parte dei programmi lo fa), li vedrai anche tu. Un programma può anche scegliere di reindirizzare o chiudere il proprio input/output standard e riutilizzare , 1 e 2 .


Linux
  1. Come reindirizzare gli URL utilizzando Nginx

  2. Linux - Tasto di scelta rapida in Linux Mint per "mostra tutte le finestre"?

  3. Reindirizzare STDERR / STDOUT di un processo DOPO che è stato avviato, utilizzando la riga di comando?

  4. Reindirizza tutto l'output su file in Bash

  5. Come eliminare tutti i file in una cartella, ma non eliminare la cartella utilizzando le librerie standard NIX?

301 Reindirizzamento utilizzando NGINX

Come reindirizzare stderr a stdout in Bash

Confuso su stdin, stdout e stderr?

Come si reindirizza la risposta wget allo standard out?

Come uccido tutti i processi di un utente usando il loro UID

bash:reindirizza stderr al file e stdout + stderr allo schermo