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.