reindirizzamento a / dev / null


144

Sto leggendo un esempio di script di shell bash:

#!/bin/bash

# This script makes a backup of my home directory.

cd /home

# This creates the archive
tar cf /var/tmp/home_franky.tar franky > /dev/null 2>&1

# First remove the old bzip2 file.  Redirect errors because this generates some if the archive
# does not exist.  Then create a new compressed file.
rm /var/tmp/home_franky.tar.bz2 2> /dev/null
bzip2 /var/tmp/home_franky.tar

# Copy the file to another host - we have ssh keys for making this work without intervention.
scp /var/tmp/home_franky.tar.bz2 bordeaux:/opt/backup/franky > /dev/null 2>&1

# Create a timestamp in a logfile.
date >> /home/franky/log/home_backup.log
echo backup succeeded >> /home/franky/log/home_backup.log

Sto cercando di capire l'uso di "/ dev / null 2> & 1" qui. All'inizio, ho pensato che questo script usasse / dev / null per ignorare con garbo gli errori, senza causare il crash dello script (un po 'come provare a catturare la gestione delle eccezioni nei linguaggi di programmazione). Perché non vedo come l'uso di tar per comprimere una directory in un file tar possa eventualmente causare qualsiasi tipo di errore.


3
Il reindirizzamento per /dev/nullnon impedire l'arresto anomalo, ma pulirà i flussi di output stdout e stderr. tarpotrebbe causare errori in vari modi. Potresti non avere accesso in scrittura, il file potrebbe già esistere, ecc.
Sparhawk

3
Solo un trucco per evitare output inutili. Per quanto riguarda il motivo per cui tar può causare errori: perché la directory di destinazione non esiste, perché la fonte non esiste, perché non si ha accesso in scrittura alla destinazione o lettura alla fonte, perché tarnon si trova in $ PATH, perché tarsi è bloccato (non si sa mai), perché non è rimasto spazio sul dispositivo, perché la tarversione è cambiata e ora richiede una sintassi diversa, perché il disco ha causato un errore I / O. Sono sicuro che potresti trovarne di più.
terdon

Risposte:


223

No, questo non impedisce l'arresto anomalo dello script. Se si verificano errori nel tarprocesso (ad esempio: permesso negato, nessun file o directory, ...) lo script continuerà a bloccarsi.

Poiché l'utilizzo > /dev/null 2>&1reindirizzerà tutto l'output del comando (sia stdoute stderr) su /dev/null, il che significa che nessun output viene stampato sul terminale.

Di default:

stdin  ==> fd 0
stdout ==> fd 1
stderr ==> fd 2

Nello script, usi > /dev/nullcausando:

stdin  ==> fd 0
stdout ==> /dev/null
stderr ==> fd 2

E quindi 2>&1causando:

stdin  ==> fd 0
stdout ==> /dev/null
stderr ==> stdout

3
A quanto > /dev/null 2>&1risulta, questo comando risulta stderr ==> stdout, quindi stderr viene ancora stampato su stdout ??
Weishi Zeng,

11
probabilmente non troppo importante, ma cos'è fd?
kev


7
Perché: CMD > /dev/null 2>&1funziona ma CMD 2>&1 > /dev/nullmi dai ancora STDERR?
dbmikus,

3
Consigliato: utilizzare 2>& 1negli esempi di codice per sottolineare che il numero e la e commerciale sono considerati parte dell'operatore di reindirizzamento. È comune che il reindirizzamento a un file abbia uno spazio tra >e /path/to/file, il reindirizzamento a un descrittore di file è essenzialmente la stessa cosa.
Henk Langeveld

21

Sto cercando di capire l'uso di "> / dev / null 2> & 1" qui.

(nota che ho aggiunto il reindirizzamento prima /dev/nullalla tua domanda.)

Quanto sopra reindirizzerebbe il STDOUTe STDERRa /dev/null. Funziona unendo il STDERRnel STDOUT. (Essenzialmente tutto l' output del comando verrebbe reindirizzato al dispositivo null .)

... senza causare l'arresto anomalo dello script (un po 'come provare a rilevare la gestione delle eccezioni nei linguaggi di programmazione).

Non è proprio come un try/catcho niente. Silenzia semplicemente qualsiasi tipo di output (incluso l'errore) dal comando.

Perché non vedo come l'uso di tar per comprimere una directory in un file tar possa eventualmente causare qualsiasi tipo di errore.

Potrebbe causare errori per una serie di motivi, tra cui:

  • Autorizzazioni inadeguate per i file su cui si sta tentando di archiviare o per i file su cui si sta tentando di scrivere
  • Mancanza di spazio su disco per creare l'archivio

ben spiegato.
Aditya Gupta,

7

Quando si esegue CMD> / dev / null 2> & 1

STDOUT reindirizza a / dev / null, quindi STDERR reindirizza a THE ADDRESS di STDOUT, che è stato impostato su / dev / null, di conseguenza sia STDOUT che STDERR puntano a / dev / null

Al contrario, quando si esegue CMD 2> & 1> / dev / null

STDERR reindirizza a L'INDIRIZZO di STDOUT (il descrittore di file 1 in quel momento, o / proc / self / fd / 1), e quindi STDOUT reindirizza a / dev / null, ma STDERR continua a reindirizzare a fd1 !! Di conseguenza, l'output normale da STDOUT viene scartato, ma gli errori provenienti da STDERR vengono ancora scritti sulla console.


-2

Reindirizzamento I / O Bash

L'idea principale per chiarire le cose è questa:

I reindirizzamenti vengono applicati da DESTRA a SINISTRA, al contrario del modo in cui normalmente parlano gli inglesi.


Quindi questo codice:

command > filename 2>&1

reindirizza stderra stdout first ( 2>&1) e quindi invia stdout(incluso il reindirizzato stderr) a filename( > filename). Ecco la spiegazione dell'ABSG (cap. 20) .

Questo codice:

command >>/dev/null 2>&1

reindirizza stderre stdoutverso /dev/null... il che significa che da nessuna parte . Le cose inviate /dev/nullnon vengono salvate, memorizzate nella cache o ricordate in alcun modo.

Sono appena inviati al " nulla " e dimenticati. Questo è un modo per eseguire i programmi e assicurarsi che non producano output e che non vengano mai visualizzati nella riga di comando o in un file di registro.


Vedo questo tipo di domanda un po '... principalmente perché ho dovuto cercarlo da solo poiché non scrivo codice da anni. Ecco alcune informazioni utili dall'ABSG:

"Reindirizzamento significa semplicemente catturare l'output da un file, comando, programma o script e inviarlo come input a un altro file, comando, programma o script."

2>&1 
# Redirects stderr to stdout.

command >>filename 2>&1
# Appends both stdout and stderr
#+  to the file "filename" ...

ABSG: Advanced Bash Scripting Guide: Il link del capitolo 20 sopra è un link alla pagina di reindirizzamento I / O del documento tldp.org open source chiamato Advanced Bash Scripting Guide di Mendel Cooper. È elencato come "Un'esplorazione approfondita dell'arte dello scripting di shell" e sono assolutamente d'accordo. È una risorsa eccezionale e ha tonnellate di risposte a ogni tipo di situazione folle.

Altre preziose risorse: ci sono molte risorse preziose nella sezione corrente / mantenuta (in diversi formati utili come html, pdf, testo, ecc.) Nella pagina delle guide ai progetti di documentazione di Linux . Eccone alcuni che ho trovato utili:


1
No, i reindirizzamenti vengono gestiti da sinistra a destra. Nel tuo esempio, l'output standard viene reindirizzato a filename, quindi l'errore standard viene reindirizzato ovunque l'output standard stia andando (a filename). Se fosse il contrario, l'errore standard sarebbe finito sul terminale mentre veniva reindirizzato solo l'output standard filename. Inoltre, in command >file1 2>file2, file2non verrebbero creati se file1non fosse possibile crearli (indipendentemente dal fatto file1che file2fossero effettivamente percorsi completamente diversi).
Kusalananda
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.