Recherche…


Syntaxe

  • commande </ path / to / file # Redirection de l'entrée standard dans le fichier
  • command> / path / to / file # Redirige la sortie standard vers flie
  • commande descripteur_fichier> / chemin / vers / fichier # Redirige la sortie de descripteur_fichier vers le fichier
  • commande> & file_descriptor # Redirige la sortie vers file_descriptor
  • commande file_descriptor> & another_file_descriptor # Redirige file_descriptor vers another_file_descriptor
  • commande <& file_descriptor # Redirige file_descriptor vers l'entrée standard
  • commande &> / path / to / file # Redirige la sortie standard et l'erreur standard vers le fichier

Paramètres

Paramètre Détails
descripteur de fichier interne Un nombre entier.
direction Un de > , < ou <>
descripteur de fichier externe ou chemin d'accès & suivi d'un entier pour le descripteur de fichier ou un chemin.

Remarques

Les programmes de la console UNIX ont un fichier d'entrée et deux fichiers de sortie (les flux d'entrée et de sortie, ainsi que les périphériques, sont traités comme des fichiers par le système d'exploitation). pour venir - ou aller à - un fichier ou un autre programme.

STDIN est une entrée standard et est la manière dont le programme reçoit une saisie interactive. STDIN est généralement STDIN descripteur de fichier 0.

STDOUT est une sortie standard. Tout ce qui est émis sur STDOUT est considéré comme le "résultat" du programme. STDOUT est généralement associé au descripteur de fichier 1.

STDERR est l'endroit où les messages d'erreur sont affichés. En règle générale, lors de l'exécution d'un programme à partir de la console, STDERR est STDERR à l'écran et ne peut pas être distingué de STDOUT . STDERR est généralement associé au descripteur de fichier 2.

L'ordre de redirection est important

command > file 2>&1

Redirige les deux ( STDOUT et STDERR ) vers le fichier.

command 2>&1 > file

Seulement redirections STDOUT , parce que le descripteur de fichier 2 est redirigé vers le fichier pointé par le descripteur de fichier 1 ( ce qui est le fichier file encore lorsque l'instruction est évaluée).

Chaque commande dans un pipeline a ses propres STDERR (et STDOUT ) car chacun est un nouveau processus. Cela peut créer des résultats surprenants si vous vous attendez à ce qu'une redirection affecte l'ensemble du pipeline. Par exemple cette commande (enveloppée pour la lisibilité):

$ python -c 'import sys;print >> sys.stderr, "Python error!"' \
| cut -f1 2>> error.log

va imprimer "erreur Python!" à la console plutôt que le fichier journal. Au lieu de cela, attachez l'erreur à la commande que vous souhaitez capturer:

$ python -c 'import sys;print >> sys.stderr, "Python error!"' 2>> error.log \
| cut -f1 

Redirection de la sortie standard

> redirige la sortie standard (aka STDOUT ) de la commande en cours dans un fichier ou un autre descripteur.

Ces exemples écrivent la sortie de la commande ls dans le fichier file.txt

ls >file.txt
> file.txt ls

Le fichier cible est créé s'il n'existe pas, sinon ce fichier est tronqué.

Le descripteur de redirection par défaut est la sortie standard ou 1 si aucun n'est spécifié. Cette commande est équivalente aux exemples précédents avec la sortie standard explicitement indiquée:

ls 1>file.txt

Remarque: la redirection est initialisée par le shell exécuté et non par la commande exécutée, elle est donc effectuée avant l'exécution de la commande.

Redirection de STDIN

< lit à partir de son argument correct et écrit dans son argument de gauche.

Pour écrire un fichier dans STDIN il faut lire /tmp/a_file et écrire dans STDIN c'est-à-dire 0</tmp/a_file

Remarque: le descripteur de fichier interne est STDIN par défaut sur 0 ( STDIN ) pour <

$ echo "b" > /tmp/list.txt
$ echo "a" >> /tmp/list.txt
$ echo "c" >> /tmp/list.txt
$ sort < /tmp/list.txt
a
b
c

Redirection à la fois STDOUT et STDERR

Les descripteurs de fichiers tels que 0 et 1 sont des pointeurs. Nous changeons ce que les descripteurs de fichiers indiquent avec la redirection. >/dev/null signifie que 1 pointe vers /dev/null .

D'abord, nous STDOUT 1 ( STDOUT ) sur /dev/null puis le point 2 ( STDERR ) sur tout ce que 1 pointe vers.

# STDERR is redirect to STDOUT: redirected to /dev/null,
# effectually redirecting both STDERR and STDOUT to /dev/null
echo 'hello' > /dev/null 2>&1
4.0

Cela peut être réduit à ce qui suit:

echo 'hello' &> /dev/null

Toutefois, cette forme peut être indésirable en production si la compatibilité du shell est un problème car elle entre en conflit avec POSIX, introduit une ambiguïté d’analyse et que les shells sans cette fonctionnalité l’interprètent de manière erronée:

# Actual code
echo 'hello' &> /dev/null
echo 'hello' &> /dev/null 'goodbye'

# Desired behavior
echo 'hello' > /dev/null 2>&1
echo 'hello' 'goodbye' > /dev/null 2>&1

# Actual behavior
echo 'hello' &
echo 'hello' & goodbye > /dev/null

REMARQUE: &> est connu pour fonctionner comme souhaité dans Bash et Zsh.

Redirection de STDERR

2 est STDERR .

$ echo_to_stderr 2>/dev/null # echos nothing

Définitions:

echo_to_stderr est une commande qui écrit "stderr" dans STDERR

echo_to_stderr () {
    echo stderr >&2
}

$ echo_to_stderr
stderr

Ajouter vs tronquer

Tronquer >

  1. Créez le fichier spécifié s'il n'existe pas.
  2. Tronquer (supprimer le contenu du fichier)
  3. Ecrire dans un fichier
$ echo "first line" > /tmp/lines
$ echo "second line" > /tmp/lines

$ cat /tmp/lines
second line

Ajouter >>

  1. Créez le fichier spécifié s'il n'existe pas.
  2. Ajouter un fichier (écriture à la fin du fichier).
# Overwrite existing file
$ echo "first line" > /tmp/lines

# Append a second line
$ echo "second line" >> /tmp/lines

$ cat /tmp/lines
first line
second line

STDIN, STDOUT et STDERR expliqués

Les commandes ont une entrée (STDIN) et deux types de sorties, la sortie standard (STDOUT) et l’erreur standard (STDERR).

Par exemple:

STDIN

root@server~# read
Type some text here

L'entrée standard est utilisée pour fournir une entrée à un programme. (Ici, nous utilisons la read intégrée pour lire une ligne de STDIN.)

STDOUT

root@server~# ls file
file

La sortie standard est généralement utilisée pour une sortie "normale" à partir d'une commande. Par exemple, ls répertorie les fichiers, de sorte que les fichiers sont envoyés à STDOUT.

STDERR

root@server~# ls anotherfile
ls: cannot access 'anotherfile': No such file or directory

L'erreur standard est (comme son nom l'indique) utilisée pour les messages d'erreur. Ce message n'étant pas une liste de fichiers, il est envoyé à STDERR.

STDIN, STDOUT et STDERR sont les trois flux standard. Ils sont identifiés à la coquille par un nombre plutôt que par un nom:

0 = standard dans
1 = Sortie standard
2 = erreur standard

Par défaut, STDIN est attaché au clavier et STDOUT et STDERR apparaissent dans le terminal. Cependant, nous pouvons rediriger STDOUT ou STDERR à tout ce dont nous avons besoin. Par exemple, supposons que vous ayez uniquement besoin de la sortie standard et que tous les messages d'erreur imprimés sur une erreur standard soient supprimés. C'est à ce moment que nous utilisons les descripteurs 1 et 2 .

Redirection de STDERR vers / dev / null
Prenant l'exemple précédent,

root@server~# ls anotherfile 2>/dev/null
root@server~#

Dans ce cas, s'il y a un STDERR, il sera redirigé vers / dev / null (un fichier spécial qui ignore tout ce qui y est placé), vous n'aurez donc aucune erreur sur le shell.

Redirection de plusieurs commandes vers le même fichier

{
  echo "contents of home directory"
  ls ~
} > output.txt

Utiliser des canaux nommés

Parfois, vous voudrez peut-être sortir quelque chose par un programme et l’entrer dans un autre programme, mais vous ne pouvez pas utiliser un canal standard.

ls -l | grep ".log"

Vous pouvez simplement écrire dans un fichier temporaire:

touch tempFile.txt
ls -l > tempFile.txt
grep ".log" < tempFile.txt

Cela fonctionne très bien pour la plupart des applications, cependant, personne ne saura ce tempFile fait tempFile et quelqu'un pourrait le supprimer s'il contient la sortie de ls -l dans ce répertoire. C'est là qu'entre en jeu un tube nommé:

mkfifo myPipe
ls -l > myPipe
grep ".log" < myPipe

myPipe est techniquement un fichier (tout est sous Linux), faisons donc ls -l dans un répertoire vide que nous venons de créer dans un tube:

mkdir pipeFolder
cd pipeFolder
mkfifo myPipe
ls -l

La sortie est la suivante:

prw-r--r-- 1 root root 0 Jul 25 11:20 myPipe

Notez le premier caractère dans les autorisations, il est répertorié comme un tube, pas un fichier.

Maintenant, faisons quelque chose de cool.

Ouvrez un terminal et notez le répertoire (ou créez-en un pour faciliter le nettoyage) et créez un canal.

mkfifo myPipe

Maintenant, mettons quelque chose dans le tuyau.

echo "Hello from the other side" > myPipe

Vous remarquerez que cela se bloque, l'autre côté du tuyau est toujours fermé. Ouvrons l'autre côté du tuyau et passons à travers.

Ouvrez un autre terminal et accédez au répertoire dans lequel se trouve le tube (ou, si vous le connaissez, ajoutez-le au tube):

cat < myPipe

Vous remarquerez qu'après la sortie de hello from the other side , le programme du premier terminal se termine, de même que celui du deuxième terminal.

Maintenant, lancez les commandes en sens inverse. Commencez avec le cat < myPipe , puis cat < myPipe écho à quelque chose. Cela fonctionne toujours, car un programme attendra que quelque chose soit mis dans le tube avant de se terminer, car il sait qu'il doit obtenir quelque chose.

Les canaux nommés peuvent être utiles pour déplacer des informations entre terminaux ou entre programmes.

Les pipes sont petites. Une fois rempli, le graveur se bloque jusqu'à ce qu'un lecteur lise le contenu. Vous devez donc exécuter le lecteur et le graveur sur différents terminaux ou exécuter l'un ou l'autre en arrière-plan:

 ls -l /tmp > myPipe &
 cat < myPipe

Plus d'exemples utilisant des canaux nommés:

  • Exemple 1 - Toutes les commandes sur le même terminal / même shell

    $ { ls -l && cat file3; } >mypipe &
    $ cat <mypipe    
    # Output: Prints ls -l data and then prints file3 contents on screen
    
  • Exemple 2 - Toutes les commandes sur le même terminal / même shell

    $ ls -l >mypipe &
    $ cat file3 >mypipe &
    $ cat <mypipe
    #Output: This prints on screen the contents of mypipe. 
    

    file3 vous que le premier contenu de file3 est affiché, puis les données ls -l sont affichées (configuration LIFO).

  • Exemple 3 - Toutes les commandes sur le même terminal / même shell

    $ { pipedata=$(<mypipe) && echo "$pipedata"; } &
    $ ls >mypipe 
    # Output: Prints the output of ls directly on screen 
    

    $pipedata vous que la variable $pipedata n'est pas utilisable dans le terminal principal / shell principal car l'utilisation de & invoque un sous-shell et que $pipedata n'est disponible que dans ce sous-shell.

  • Exemple 4 - Toutes les commandes sur le même terminal / même shell

    $ export pipedata
    $ pipedata=$(<mypipe) &
    $ ls -l *.sh >mypipe
    $ echo "$pipedata"   
    #Output : Prints correctly the contents of mypipe
    

    Cela imprime correctement la valeur de la variable $pipedata dans le shell principal en raison de la déclaration d'exportation de la variable. Le terminal principal / shell principal n'est pas bloqué en raison de l'invocation d'un shell d'arrière-plan ( & ).

Imprimer les messages d'erreur sur stderr

Les messages d'erreur sont généralement inclus dans un script à des fins de débogage ou pour fournir une expérience utilisateur enrichie. Il suffit d'écrire un message d'erreur comme ceci:

cmd || echo 'cmd failed'

peut fonctionner pour des cas simples mais ce n'est pas la manière habituelle. Dans cet exemple, le message d'erreur pollue la sortie réelle du script en mélangeant les erreurs et la sortie réussie dans stdout .

En bref, le message d'erreur devrait aller à stderr pas stdout . C'est assez simple:

cmd || echo 'cmd failed' >/dev/stderr

Un autre exemple:

if cmd; then
    echo 'success'
else
    echo 'cmd failed' >/dev/stderr
fi

Dans l'exemple ci-dessus, le message de réussite sera imprimé sur stdout tandis que le message d'erreur sera imprimé sur stderr .

Une meilleure façon d’imprimer un message d’erreur est de définir une fonction:

err(){
    echo "E: $*" >>/dev/stderr
}

Maintenant, quand vous devez imprimer une erreur:

err "My error message"

Redirection vers les adresses réseau

2,04

Bash considère certains chemins comme spéciaux et peut communiquer avec le réseau en écrivant dans /dev/{udp|tcp}/host/port . Bash ne peut pas configurer un serveur d'écoute, mais peut initier une connexion, et pour TCP, il peut au moins lire les résultats.

Par exemple, pour envoyer une simple requête Web, vous pouvez:

exec 3</dev/tcp/www.google.com/80
printf 'GET / HTTP/1.0\r\n\r\n' >&3
cat <&3

et les résultats de la page Web par défaut de www.google.com seront imprimés sur stdout .

De même

printf 'HI\n' >/dev/udp/192.168.1.1/6666

enverrait un message UDP contenant HI\n à un auditeur sur 192.168.1.1:6666



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow