La première chose à noter est qu'il y a deux façons en fonction de votre objectif et de votre shell, donc cela nécessite une légère compréhension de plusieurs aspects. De plus, certaines commandes telles que time
et strace
ecrire la sortie dans stderr par défaut, et peut 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 généré par shell (en supposant qu'il s'agit d'une commande externe et non d'un shell intégré) est créé via fork()
et execve()
appels système, et avant que cela ne se produise un autre appel système dup2()
effectue les redirections nécessaires avant execve()
arriver. En ce sens, les redirections sont héritées du shell parent. Le m&>n
et m>n.txt
informez le shell sur la façon de procéder open()
et dup2()
syscall (voir aussi Comment fonctionne la redirection d'entrée, Quelle est la différence entre redirection et pipe, et Que signifie exactement & dans la redirection de sortie )
Redirections de Shell
Le plus typique, est via 2>
dans Coquilles en forme de Bourne, notamment dash
(qui est lié symboliquement à /bin/sh
) et bash
le premier est le shell par défaut et compatible POSIX et l'autre est ce que la plupart des utilisateurs utilisent pour une session interactive. Ils diffèrent par la syntaxe et les fonctionnalités, mais heureusement pour nous, la redirection de flux d'erreurs fonctionne de la même manière (sauf le &>
non standard). Dans le cas de csh et de ses dérivés, la redirection stderr ça ne marche pas tout à fait là-bas.
Revenons à 2>
partie. Deux choses clés à remarquer: >
signifie opérateur de redirection, où nous ouvrons un fichier et 2
integer signifie descripteur de fichier stderr; en fait, c'est exactement ainsi que la norme POSIX pour le langage shell définit la redirection dans section 2.7:
[n]redir-op word
Pour simple >
redirection, le 1
entier est implicite pour stdout
, i.e. echo Hello World > /dev/null
c'est exactement la même chose que echo Hello World 1>/dev/null
. Notez que l'opérateur entier ou de redirection ne peut pas être entre guillemets, sinon le shell ne les reconnaît pas en tant que tels et les traite à la place comme une chaîne de texte littérale. En ce qui concerne l'espacement, il est important que integer soit juste à côté de l'opérateur de redirection, mais file peut être à côté de l'opérateur de redirection ou non, c'est-à-dire command 2>/dev/null
et command 2> /dev/null
fonctionnera très bien.
La syntaxe quelque peu simplifiée pour une commande typique dans le shell serait
command [arg1] [arg2] 2> /dev/null
L'astuce ici est que la redirection peut apparaître n'importe où. C'est les deux 2> command [arg1]
et command 2> [arg1]
sont valides. Notez que pour bash
coquille, là il existe &>
un moyen de rediriger les flux stdout et stderr en même temps, mais encore une fois - c'est spécifique à bash et si vous recherchez la portabilité des scripts, cela peut ne pas fonctionner. Voir aussi Wiki Ubuntu et >>Quelle est la différence entre & et 2& 1.
Note: Le >
opérateur de redirection tronquer un fichier et l'écrase, si le fichier existe. Le 2>>
peut être utilisé pour l'ajout stderr
déposer.
Si vous remarquez, >
est destiné à une seule commande. Pour les scripts, nous pouvons rediriger le flux stderr de l'ensemble du script de l'extérieur comme dans myscript.sh 2> /dev/null
ou nous pouvons utiliser exec intégré. 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 un script. Quelque chose comme
#!/bin/shexec 2> ./my_log_file.txtstat /etc/non_existing_file
Dans cet exemple, le fichier journal doit afficher stat: cannot stat '/etc/non_existing_file': No such file or directory
.
Encore une autre façon est via les fonctions. Comme Cendrillon noté dans sa réponse, nous pouvons écrire une déclaration de fonction avec une redirection déjà jointe, c'est-à-dire
some_function(){ command1 command2} 2> my_log_file.txt
Commandes écrivant exclusivement dans stderr
Commandes telles que time
et strace
écrivez leur sortie dans stderr par défaut. En cas de time
commande, 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, la liste synchrone ou le sous-shell peut être redirigé si vous souhaitez séparer la sortie ( comme indiqué dans article connexe ):
{ time sleep 1 2> sleep.stderr ; } 2> time.txt
D'autres commandes, telles que strace
ou dialog
fournir des moyens de rediriger stderr. strace
avoir -o <filename.txt>
option qui permet de spécifier le nom du fichier où la sortie doit être écrite. Il existe également une option pour écrire un fichier texte pour chaque sous-processus qui strace
voir. Le dialog
la commande écrit l'interface utilisateur textuelle dans stdout mais la sortie dans stderr, afin de enregistrer sa sortie dans la variable ( parce var=$(...)
et les pipelines ne reçoivent 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
drapeau, que nous pouvons également utiliser. Il y a aussi la méthode des tuyaux nommés. Je recommande de lire le post lié sur le dialog
commande pour une description complète de ce qui se passe.