redirection vers / dev / null

144

Je lis un exemple de script 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

J'essaie de comprendre l'utilisation de "/ dev / null 2> & 1" ici. Au début, je pensais que ce script utilisait / dev / null pour ignorer les erreurs sans provoquer le plantage du script (un peu comme essayer de gérer les exceptions dans les langages de programmation). Parce que je ne vois pas comment utiliser tar pour compresser un répertoire dans un fichier tar pourrait éventuellement provoquer tout type d'erreur.

JohnMerlino
la source
3
La redirection vers /dev/nulln'empêche pas le crash, mais nettoie les flux de sortie stdout et stderr. tarpourrait causer des erreurs de diverses manières. Vous n'avez peut-être pas accès en écriture, le fichier existe peut-être déjà, etc.
Sparhawk
3
Juste un truc pour éviter les sorties inutiles. Pourquoi tar peut provoquer des erreurs: parce que le répertoire cible n’existe pas, parce que la source n’existe pas, parce que vous n’avez pas d’accès en écriture à la cible, ni en lecture sur la source, car tarn’est pas dans votre $ PATH, car tars'est écrasé (on ne sait jamais), car il ne reste plus d'espace sur le périphérique, car la tarversion a changé et requiert une syntaxe différente, car le disque a provoqué une erreur d'E / S. Je suis sûr que vous pourriez en trouver plus.
terdon

Réponses:

223

Non, cela n'empêchera pas le script de planter. Si des erreurs se produisent dans le tarprocessus (par exemple: permission refusée, aucun fichier ou répertoire de ce type, ...), le script se plante quand même.

Parce que using > /dev/null 2>&1redirige toutes les sorties de votre commande (les deux stdoutet stderr) vers /dev/null, ce qui signifie qu'aucune sortie n'est imprimée sur le terminal.

Par défaut:

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

Dans le script, vous utilisez > /dev/nullcausant:

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

Et puis 2>&1causant:

stdin  ==> fd 0
stdout ==> /dev/null
stderr ==> stdout
cuonglm
la source
3
Au vu de la compréhension > /dev/null 2>&1, cette commande a pour résultat stderr ==> stdoutque stderr est toujours imprimé sur stdout?
Weishi Zeng
11
probablement pas trop important, mais qu'est-ce que c'est fd?
kev
7
Pourquoi fonctionne-t-il CMD > /dev/null 2>&1mais CMD 2>&1 > /dev/nullme donne-t- il encore STDERR?
dbmikus
3
Recommandé: utilisez, 2>& 1dans les exemples de code, pour souligner que le nombre et l'esperluette sont considérés comme faisant partie de l'opérateur de redirection. Il est courant que la redirection vers un fichier ait un espace entre >et /path/to/file, la redirection vers un descripteur de fichier est essentiellement la même chose.
Henk Langeveld
21

J'essaie de comprendre l'utilisation de "> / dev / null 2> & 1" ici.

(Notez que j'ai déjà ajouté la redirection /dev/nulldans votre question.)

Ce qui précède redirige le STDOUTet STDERRvers /dev/null. Cela fonctionne en fusionnant STDERRle STDOUT. (Essentiellement, toute la sortie de la commande serait redirigée vers le périphérique null .)

... sans provoquer le plantage du script (un peu comme essayer de gérer les exceptions dans les langages de programmation).

Ce n'est pas vraiment comme un try/catchou quoi que ce soit. Il supprime simplement tout type de sortie (y compris d'erreur) de la commande.

Parce que je ne vois pas comment utiliser tar pour compresser un répertoire dans un fichier tar pourrait éventuellement provoquer tout type d'erreur.

Cela pourrait entraîner des erreurs pour un certain nombre de raisons, notamment:

  • Autorisations inadéquates sur le ou les fichiers que vous essayez d'archiver ou sur le fichier sur lequel vous essayez d'écrire
  • Manque d'espace disque pour créer l'archive
devnull
la source
bien expliqué.
Aditya Gupta le
7

Lorsque vous exécutez CMD> / dev / null 2> & 1

STDOUT redirige vers / dev / null, puis STDERR redirige vers THE ADDRESS de STDOUT, qui a été défini sur / dev / null; par conséquent, STDOUT et STDERR pointent vers / dev / null.

Inversement, lorsque vous exécutez CMD 2> & 1> / dev / null

STDERR redirige vers L'ADRESSE de STDOUT (le descripteur de fichier 1 à cet instant, ou / proc / self / fd / 1), puis STDOUT redirige vers / dev / null, mais STDERR continue de rediriger vers fd1 !! En conséquence, la sortie normale de STDOUT est supprimée, mais les erreurs provenant de STDERR sont toujours écrites sur la console.

Hector
la source
-2

Redirection Bash I / O

L'idée principale pour clarifier les choses est la suivante:

Les redirections sont appliquées de DROITE à GAUCHE, contrairement à la façon dont les anglophones lisent normalement.


Donc ce code:

command > filename 2>&1

redirige stderrvers stdout first ( 2>&1) puis envoie stdout(incluant le redirigé stderr) to filename( > filename). Voici l'explication de l'ABSG (Ch. 20) .

Ce code:

command >>/dev/null 2>&1

redirections stderret stdoutvers /dev/null... ce qui signifie nulle part . Les éléments envoyés à /dev/nullne sont en aucun cas sauvegardés, mis en cache ou mémorisés.

Ils sont simplement envoyés dans « nulle part » et oubliés. C'est une façon d'exécuter des programmes et de s'assurer qu'ils ne produisent AUCUNE sortie et qu'ils ne seront jamais vus sur la ligne de commande ou dans un fichier journal.


Je vois ce type de question un peu ... principalement parce que je dois le chercher moi-même depuis que je ne code pas depuis des années. Voici quelques informations utiles de l'ABSG:

"La redirection signifie simplement capturer la sortie d'un fichier, d'une commande, d'un programme ou d'un script et l'envoyer en tant qu'entrée dans un autre fichier, commande, programme ou script."

2>&1 
# Redirects stderr to stdout.

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

ABSG: Guide de script avancé Bash: Le lien du chapitre 20 ci - dessus est un lien vers la page de redirection des E / S du document open source tldp.org appelé Guide de script avancé de Bash par Mendel Cooper. Il est répertorié comme "une exploration en profondeur de l'art de l'écriture de scripts shell" et je suis absolument d'accord. C'est une ressource formidable qui offre une multitude de réponses à toutes sortes de situations délirantes.

Autres ressources précieuses: Il existe de nombreuses ressources précieuses dans la section en cours / mise à jour (dans plusieurs formats pratiques tels que html, pdf, texte, etc.) sur la page Guides de projet de documentation Linux . Voici quelques exemples que j'ai trouvés utiles:

Sceptique
la source
1
Non, les redirections sont traitées de gauche à droite. Dans votre exemple, la sortie standard est redirigée vers filename, puis l'erreur standard est redirigée là où la sortie standard est actuellement (vers filename). Si c'était le contraire, l'erreur standard se retrouverait sur le terminal alors que seule la sortie standard serait redirigée filename. En outre, dans command >file1 2>file2, file2ne serait pas créé s'il file1ne pouvait pas être créé (peu importe si file1et file2étaient en fait des noms de chemins totalement différents).
Kusalananda