572 votes

Comment rediriger stderr vers un fichier

En utilisant nohup pour mettre une commande à exécuter en arrière-plan, certains contenus apparaissent dans le terminal.

cp: error reading ‘/mnt/tt/file.txt’: Input/output error
cp: failed to extend ‘/mnt/tt/file.txt’: Input/output error

Je veux enregistrer ce contenu dans un fichier.

983voto

Stewart Points 1385

Il existe deux flux de sortie principaux sous Linux (et d'autres systèmes d'exploitation), la sortie standard (stdout) et l'erreur standard (stderr). Les messages d'erreur, comme ceux que vous affichez, sont imprimés sur l'erreur standard. L'opérateur de redirection classique ( command > file ) redirige seulement la sortie standard, donc l'erreur standard est toujours affichée sur le terminal. Pour rediriger également stderr, vous avez plusieurs choix :

  1. Redirige stdout vers un fichier et stderr vers un autre fichier :

    command > out 2>error
  2. Rediriger stdout vers un fichier ( >out ), et ensuite rediriger stderr vers stdout ( 2>&1 ):

    command >out 2>&1
  3. Rediriger les deux vers un fichier (ceci n'est pas supporté par tous les shells, bash y zsh le soutenir, par exemple, mais sh y ksh ne le font pas) :

    command &> out

Pour plus d'informations sur les différents opérateurs de contrôle et de redirection, voir aquí .

31voto

Sergiy Kolodyazhnyy Points 97292

La première chose à noter est qu'il y a plusieurs façons de procéder en fonction de votre objectif et du Shell, donc cela nécessite une légère compréhension de plusieurs aspects. De plus, certaines commandes telles que time y strace écrivent la sortie sur stderr par défaut, et peuvent ou non fournir une méthode de redirection spécifique à cette commande

La théorie de base derrière la redirection est qu'un processus engendré par Shell (en supposant qu'il s'agit d'une commande externe et non d'un Shell intégré) est créé par l'intermédiaire de fork() y execve() syscalls, et avant que cela n'arrive, un autre syscall dup2() effectue les redirections nécessaires avant execve() arrive. En ce sens, les redirections sont héritées du parent Shell. Le site m&>n y m>n.txt informer le Shell sur la façon d'effectuer open() y dup2() syscall (voir aussi Comment fonctionne la redirection des entrées , Quelle est la différence entre redirection et pipe y Que signifie exactement & dans la redirection de sortie )

Shell

Le plus souvent, c'est via 2> en Les shells de type Bourne comme dash (qui est lié par un lien symbolique à /bin/sh ) et bash ; le premier est le Shell par défaut et conforme à POSIX et l'autre est ce que la plupart des utilisateurs utilisent pour les sessions interactives. Ils diffèrent dans leur syntaxe et leurs fonctionnalités, mais heureusement pour nous, la redirection des flux d'erreurs fonctionne de la même manière (sauf le paramètre &> non standard). Dans le cas de csh et ses dérivés, la redirection stderr ne fonctionne pas tout à fait là.

Revenons à 2> partie. Deux choses essentielles à noter : > signifie opérateur de redirection, dans lequel nous ouvrons un fichier et 2 integer représente le descripteur de fichier stderr ; en fait, c'est exactement comme cela que la norme POSIX pour le langage Shell définit la redirection en section 2.7 :

[n]redir-op word

Pour les simples > la redirection, la 1 entier est implicite pour stdout c'est-à-dire echo Hello World > /dev/null c'est la même chose que echo Hello World 1>/dev/null . Notez, que l'entier ou l'opérateur de redirection ne peuvent pas être cités, sinon Shell ne les reconnaît pas comme tels, et les traite plutôt comme une chaîne de texte littérale. En ce qui concerne l'espacement, il est important que l'entier soit juste à côté de l'opérateur de redirection, mais le fichier peut être à côté de l'opérateur de redirection ou non, c'est à dire command 2>/dev/null y command 2> /dev/null fonctionnera très bien.

La syntaxe quelque peu simplifiée de la commande typique dans Shell serait la suivante

 command [arg1] [arg2]  2> /dev/null

L'astuce ici est que la redirection peut apparaître n'importe où. C'est-à-dire à la fois 2> command [arg1] y command 2> [arg1] sont valables. Notez que pour bash Shell, il existe &> moyen de rediriger les deux flux stdout et stderr en même temps, mais encore une fois - c'est spécifique à bash et si vous vous efforcez de la portabilité des scripts, cela peut ne pas fonctionner. Voir aussi Wiki Ubuntu y Quelle est la différence entre &> et 2>&1 .

Nota: Le site > opérateur de redirection tronqué un fichier et l'écrase, si le fichier existe. Le site 2>> peut être utilisé pour ajouter stderr à classer.

Si vous avez remarqué, > est destiné à une seule commande. Pour les scripts, nous pouvons rediriger le flux stderr de tout le scripts de l'extérieur comme dans myscript.sh 2> /dev/null ou nous pouvons utiliser Exécution intégrée . L'exec intégré a le pouvoir de recâbler le flux pour toute la session Shell, pour ainsi dire, que ce soit de manière interactive ou via Shell. Quelque chose comme

#!/bin/sh
exec 2> ./my_log_file.txt
stat /etc/non_existing_file

Dans cet exemple, le fichier journal devrait montrer stat: cannot stat '/etc/non_existing_file': No such file or directory .

Une autre façon de procéder est d'utiliser les fonctions. Comme kopciuszek noté dans sa réponse, nous pouvons écrire une déclaration de fonction avec une redirection déjà attachée, c'est-à-dire

some_function(){
    command1
    command2
} 2> my_log_file.txt

Commandes écrivant exclusivement sur stderr

Des commandes telles que time y strace écrivent leur sortie sur stderr par défaut. En cas de time la seule alternative viable est de rediriger la sortie de la commande entière, c'est-à-dire

time echo foo 2>&1 > file.txt

Alternativement, une liste synchrone ou un subshell peuvent être redirigés si vous voulez séparer la sortie ( comme indiqué dans poste connexe ):

{ time sleep 1 2> sleep.stderr ; } 2> time.txt

D'autres commandes, telles que strace o dialog fournir des moyens de rediriger stderr. strace a -o <filename.txt> option qui permet de spécifier le nom du fichier où la sortie doit être écrite. Il existe également une option permettant d'écrire un fichier texte pour chaque sous-processus que strace voit. Le site dialog écrit l'interface utilisateur textuelle sur stdout mais la sortie sur stderr, donc afin de enregistre sa sortie dans la variable ( parce que var=$(...) et pipelines ne reçoit que stderr ) nous devons échanger les descripteurs de fichiers

result=$(dialog --inputbox test 0 0 2>&1 1>/dev/tty);

mais en plus, il y a --output-fd que nous pouvons également utiliser. Il y a aussi la méthode des tuyaux nommés. Je vous recommande de lire le billet lié à propos de la méthode dialog pour une description détaillée de ce qui se passe.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X