Comment supprimer la sortie d'une commande mais l'afficher si la sortie de la commande code une erreur?
Malheureusement, l'hypothèse qui stderr
n'est utilisée que pour la sortie d'erreur n'est pas toujours correcte. Au contraire, stderr
est souvent utilisé pour toutes les sorties et tous les diagnostics interactifs , c'est-à-dire les sorties destinées à être lues par l'utilisateur dans une invite interactive 1 . wget
et dd
sont des exemples bien connus.
Certaines commandes fourniront un indicateur (par exemple -quiet
ou -silent
) pour supprimer la sortie sans erreur - lisez leurs pages de manuel pour voir s'il en existe une.
Une autre convention qui tient plus souvent est le code de sortie : un programme retourne un code de sortie quand il se termine. En général 2 , un code de sortie de 0
indique le succès et tout autre code de sortie indique une erreur.
Avec bash
, vous pouvez obtenir le code de sortie de la dernière commande à partir de la $?
variable. Dans fish
, utilisez la $status
variable. Vous pouvez diriger stderr
vers un fichier temporaire et l'imprimer uniquement en cas d'erreur. Par exemple ( fish
):
command 2>/tmp/outputbuffer
if $status
cat /tmp/outputbuffer
rm /tmp/outputbuffer
Vous pouvez également utiliser des raccourcis, si vous ne chaînez pas de commandes:
if command 2>/tmp/outputbuffer
cat /tmp/outputbuffer
rm /tmp/outputbuffer
Ou:
command 2>/tmp/outputbuffer; or cat /tmp/outputbuffer; rm /tmp/outputbuffer;
Vous pouvez également diriger stdout
vers le même tampon à l'aide de 2>&1 >/tmp/outputbuffer
.
(Remarque: je ne sais pas vraiment fish
, donc j'adapte le concept à ce que je peux trouver dans sa documentation. La syntaxe peut être légèrement erronée. De plus, vous pouvez utiliser mktemp
pour générer un fichier temporaire unique - exécutez-le et enregistrez le nom de fichier dans une variable.)
Si vous devez exécuter le tout en arrière-plan d'un shell que vous utilisez également de manière interactive en même temps, vous feriez mieux d'écrire un script pour gérer le masquage de sortie et d'exécuter ce script en arrière-plan avec les techniques standard ( fish
). Heck, vous pouvez mettre quelque chose comme la fonction suivante dans ~/.config/fish/config.fish
:
function run-silent
set temp (mktemp)
if $argv 2>&1 >$temp
cat $temp
rm $temp
end
Appelez avec run-silent somecommand &
(où la fin le &
fait fonctionner en arrière-plan)
Notez que cela avalera le code de sortie d'origine et videra à la fois stdout
et stderr
en cas d'échec. Vous pouvez le personnaliser si nécessaire.
1 Il n'y a même pas de garantie que la sortie d'erreur n'apparaîtra pas stdout
- certains programmes y déverseront toutes les sorties!
2 Malheureusement, cela est toujours pas toujours le cas - le code de la sortie est entièrement contrôlé par le programme, et certains indiquent certaines conditions de succès avec les sorties non nulles. Encore une fois, consultez le manuel.
Les utilitaires Unix envoient des messages généraux à
stdout
et des messages d'erreur àstderr
, donc si nous voulons seulement voir les messages d'erreur, alors il suffira de les supprimer pour n'obtenirstdout
que lastderr
sortie sur la console.La façon de procéder (dans les deux
bash
etfish
) consiste à ajouter>/dev/null
à la commande. Cela envoie stdout dans le néant, mais stderr (avec vos messages d'erreur) parvient toujours à la console.Ainsi, par exemple:
La commande
echo 1 >/dev/null
n'imprime rien, car lastdout
sortie normale est supprimée et rien n'a été écrit sur stderr.La commande
man doesnotexist >/dev/null
imprime un message d'erreur, carman
écrit son message d'erreur dansstderr
.la source
Cela exécutera la commande en arrière-plan et écrira les erreurs dans un fichier journal en ignorant la sortie normale
la source