@Tadlos aka Soldat Ryan

{1} Shell Redirections

Quizz

Shell Redirections

Shell Redirections

stdin/stdout/stderr

Chaque processus UNIX/Linux a au moins trois descripteurs de fichiers ouverts par défaut :

FD Nom Utilisation par le processus Destination par défaut
0 stdin read() Entrée standard (clavier)
1 stdout write() Sortie standard (écran)
2 stderr write() Erreur standard (écran)

Un file descriptor (fd) = un pointeur vers un fichier.

Shell Redirections

PTS : Pseudo-Terminal Slave

Afficher les fd du shell courant :

$ ls -l /proc/$$/fd
total 0
lrwx------ 1 tadlos tadlos 64 8 mai 15:30 0 -> /dev/pts/0
lrwx------ 1 tadlos tadlos 64 8 mai 15:30 1 -> /dev/pts/0
lrwx------ 1 tadlos tadlos 64 8 mai 15:30 2 -> /dev/pts/0
lrwx------ 1 tadlos tadlos 64 8 mai 15:30 255 -> /dev/pts/0
			

/dev/pts/0 étant un fichier spécial représentant une session de terminal.

Shell Redirections

Rediriger un fd vers un autre fd

On utilise toujours le signe & devant un descripteur de fichiers, à droite du symbole de redirection.

3>&4 >&2
2>&1 2>&3

Dans la syntaxe n>&mn et m sont des file descriptors,
si n n'est pas spécifié, c'est le file descriptor 1 (stdout) qui est pris en compte par défaut.

Shell Redirections

Rediriger un fd vers un autre fd

Ce n'est pas un lien dynamique.
Le shell copie ce vers quoi pointe actuellement fd1 et assigne cette même cible à fd2.

2>&1

Shell Redirections

Exemples de redirections

# redirige stdout vers le fichier /tmp/out
ps aux > /tmp/out
# redirige stderr vers le fichier /tmp/err
ps aux 2> /tmp/err
# redirige stderr vers stdout
ps aux 2>&1 

S'il y en a plusieurs, les redirections s'exécutent de gauche à droite.

Shell Redirections

Rediriger stdout&stderr

Exemple d'un programme program.sh qui redirige la chaîne out dans stdout et redirige la chaîne err dans stderr

$ cat program.sh
#!/bin/bash
# stdout et stderr sont rattachés au tty /dev/pts/0
echo "out"			# redirige "out" vers stdout
echo "err" >&2	# redirige "err" vers stderr

$ ./program.sh
out
err

$ ./program.sh >/dev/null # stdout est redirigé vers /dev/null
err

$ ./program.Sh 2>/dev/null # stderr est redirigé vers /dev/null
out

Shell Redirections

Rediriger stdout&stderr

$ cat program.sh

#!/bin/bash
echo "out"
echo "err" >&2

Comment faire pour rediriger stdout et stderr dans le même fichier out.err.

Shell Redirections

Rediriger stdout&stderr

$ ./program.sh 2>&1 > out.err

État initial : Les file descriptors du shell sont initialement rattachés au terminal de la session en cours (e.g./dev/pts/0).

  • [stdout] 1 -> /dev/pts/0
  • [stderr] 2 -> /dev/pts/0

Shell Redirections

Rediriger stdout&stderr

$ ./program.sh 2>&1 > out.err

Rappel : Les redirections se font de gauche à droite.

Étape 1 :
stderr ("fd2") est rattaché à stdout("fd1"), qui était lui-même rattaché au terminal (/dev/pts/0)
Donc "err" est envoyé sur le terminal

  • [stdout] 1 -> /dev/pts/0
  • [stderr] 2 -> &1 (/dev/pts/0)

Shell Redirections

Rediriger stdout&stderr

$ ./program.sh 2>&1 > out.err

Étape 2 : stdout ("fd1") est rattaché au fichier out.err

  • [stdout] 1 -> out.err
  • [stderr] 2 -> &1 (/dev/pts/0)

Shell Redirections

Rediriger stdout&stderr

Donc, comment rediriger stdout et stderr dans le même fichier ?
Il faut bien choisir le sens :

$ ./program.sh > out.err 2>&1

Shell Redirections

Rediriger stdout&stderr

$ ./program.sh > out.err 2>&1

Étape 1 :

  • [stdout] 1 -> out.err
  • [stderr] 2 -> /dev/pts/0

Shell Redirections

Rediriger stdout&stderr

$ ./program.sh > out.err 2>&1

Étape 2 :

  • [stdout] 1 -> out.err
  • [stderr] 2 -> &1 (out.err)

Shell Redirections

&> ou >&

équivalent de : > [file] 2>&1

./program.sh >& out.err
./program.sh &> out.err

C'est sémantiquement équivalent à ./program.sh > out.err 2>&1
Permet de rediriger à la fois stdout et stderr sans se tromper.

Shell Redirections

&> ou >&

équivalent de : > [file] 2>&1

La première forme (&>file) est recommandée.

En effet, la forme >&file est ambigüe car :

  • Si file est un nombre, le shell va penser qu'il s'agit d'un fd.
  • Si file est un "-", le shell va penser que l'on souhaite fermer un fd.

When using the second form, [file] may not expand to a number or ‘-’.
If it does, other redirection operators apply (see Duplicating File Descriptors) for compatibility reasons.

Shell Redirections

Shell Redirections

Le pipe

Le pipe permet de connecter la sortie standard (stdout) du processus de gauche avec l'entrée standard (stdin) du processus de droite.

[command] | [command2]

Connecte stdout du process command au stdin du process command2
Pour cela, le shell utilise les appels système pipe2 et dup2 (ou dup3).

Shell Redirections

int pipe2(int pipefd[2], int flags);

  • pipfd[0] : fd pour lire dans le pipe (read_end)
  • pipfd[1] : fd pour écrire dans le pipe (write_end)

Tout ce qui est écrit dans pipefd[1] peut être lu depuis pipefd[0].

Shell Redirections

int dup2(int oldfd, int newfd);

Ensuite, l'appel système dup2() est utilisé (ou dup3).
Il permet de dupliquer le descripteur oldfd sur newfd.

C'est-à-dire que le nouveau descripteur (newfd) pointe sur la même ressource que l'ancien descripteur (olfd).

newfd -> &oldfd

Shell Redirections

Exemple

echo "Tadlos" | grep "t"

État initial

Shell Redirections

echo "Tadlos" | grep "t"

pipe2() va créer 2 descripteurs de fichiers : pipe([3, 4])
pipfd[0] = fd3
pipfd[1] = fd4

Shell Redirections

echo "Tadlos" | grep "t"

dup2() va dupliquer fd1 du process lié à echo sur fd4 lié au pipe

dup2(4, 1)

Shell Redirections

echo "Tadlos" | grep "t"

Pareil avec fd0 lié au process grep sur fd3 lié au pipe.

dup2(3, 0)

Shell Redirections

Shell Redirections

Les priorités

Shell Redirections

unknowncommand 2>&1 >/tmp/out | grep –o "unknowncommand"

Le pipe est prioritaire aux redirections.

Shell Redirections

D'abord, la connexion avec le pipe est prioritaire et faite en premier.

Shell Redirections

Ensuite, la première redirection tout à gauche est appliquée.
stderr pointe sur stdout, qui pointe lui-même sur l'extrémité d'écriture du pipe (fd4).

Shell Redirections

Puis, la redirection suivante est appliquée.
stdout pointe sur le fichier /tmp/out.

Shell Redirections

La commande echo est exécutée, ce qui provoque l'envoi d'une erreur "unknowncommand: commande introuvable" sur stderr connecté au pipe.

Shell Redirections

Enfin, la commande grep reçoit en entrée (stdin) le flux d'erreur via l'extrémité de lecture du pipe (fd3).
L'option -o de grep affiche uniquement la chaîne recherchée dans la ligne.

Shell Redirections

Shell Redirections

|&

équivalent de : [command] 2>&1 |[command2]

Permet de rediriger et la sortie standard et la sortie d'erreur dans le pipe.

Shell Redirections

Shell Redirections

|&

Attention, cette syntaxe change la règle des priorités.
Dans ce cas, le pipe n'est plus prioritaire.

Shell Redirections

Contact: tadlos.nayr@proton.me

@Tadlos aka Soldat Ryan