Comment exécuter une commande en arrière-plan sans sortie sauf en cas d'erreur

14

Comment supprimer la sortie d'une commande mais l'afficher si la sortie de la commande code une erreur?

Xster
la source

Réponses:

17

Malheureusement, l'hypothèse qui stderrn'est utilisée que pour la sortie d'erreur n'est pas toujours correcte. Au contraire, stderrest 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 . wgetet ddsont des exemples bien connus.

Certaines commandes fourniront un indicateur (par exemple -quietou -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 0indique 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 $statusvariable. Vous pouvez diriger stderrvers 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 stdoutvers 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 mktemppour 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 stdoutet stderren 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.

Bob
la source
légère modification du poisson, il y a une place spéciale pour mettre des fonctions dans ~ / .config / fish / functions /
Xster
12

Les utilitaires Unix envoient des messages généraux à stdoutet des messages d'erreur à stderr, donc si nous voulons seulement voir les messages d'erreur, alors il suffira de les supprimer pour n'obtenir stdoutque la stderrsortie sur la console.

La façon de procéder (dans les deux bashet fish) 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/nulln'imprime rien, car la stdoutsortie normale est supprimée et rien n'a été écrit sur stderr.

La commande man doesnotexist >/dev/nullimprime un message d'erreur, car manécrit son message d'erreur dans stderr.

Maximillian Laumeister
la source
2

Cela exécutera la commande en arrière-plan et écrira les erreurs dans un fichier journal en ignorant la sortie normale

    command > /dev/null 2> /tmp/example_error.log &
Genkus
la source