Redirection de la sortie du programme

11

Lorsque vous essayez de rediriger la sortie du programme avec la syntaxe "un certain nombre supérieur à" (par exemple foo 2> myfile), quels sont les nombres possibles ici et que représentent-ils?

Je crois que 1 est /dev/stdout, 2 est /dev/stderr. Et 5 et 6? Y a-t-il 3, 4 ou un nombre supérieur à 6?

L'élève de Fermat
la source
Voir aussi Quand utiliseriez-vous un descripteur de fichier supplémentaire?
Gilles 'SO- arrête d'être méchant'

Réponses:

11

Ce programme supposé écrira le numéro de descripteur de fichier que vous avez spécifié. considérez le programme Hello World suivant:

#include <stdio.h>

main()
{
   ssize_t i = 0 ;
   printf ("hello world\n") ;
   i = write( 5 , "Bonjour Monde\n", 14 ) ;
   printf ("%d octet dans 5\n", (int) i) ;
}

compilez-le

me@mybox:~/tmp7$ make hw
cc     hw.c   -o hw

maintenant une course simple

me@mybox:~/tmp7$ ./hw
hello world
-1 octet dans 5

pas de fichier pour 5, donc pas d'octet écrit.

essayez ensuite:

me@mybox:~/tmp7$ ./hw 5> u
hello world
14 octet dans 5
me@mybox:~/tmp7$ cat u
Bonjour Monde

J'arrive à obtenir une sortie tout en spécifiant un fichier et un descripteur de fichier (par exemple 5>u).

En pratique, à moins d'avoir écrit un programme aussi amusant que ci-dessus, il est peu probable que vous collectiez des données à l'aide 5>foo.

dans le script shell, les constructions utilisant <() sont plus utiles:

 diff <( cmd -par 1 ) <(cmd -par 2)
Archemar
la source
write()renvoie ssize_t, non int.
Andrew Henle
Ce n'est pas le point principal de la question, il y a aussi un retour pour la fonction printf.
Archemar
Ne pas utiliser de valeur renvoyée est très différent de l'utilisation d'un mauvais type .
Andrew Henle
édité je ne vois aucun changement dans la sortie ...
Archemar
10

Les nombres représentent les descripteurs de fichiers (gère les fichiers qui ont été ouverts).

La coque a généralement 3 ensembles automatiquement,

0 - stdin 1 - stdout 2 - stderr

Mais d'autres fichiers peuvent être ouverts et les nombres augmentent.

X Tian
la source
7

Ces nombres sont des descripteurs de fichiers . Comme vous l'avez noté, plusieurs sont créés automatiquement. Au fur et à mesure que d'autres fichiers ou éléments similaires sont ouverts, ils obtiennent d'autres numéros.

Les nombres utilisés dans un programme particulier dépendent des fichiers ouverts par ce programme ou utilisés d'une autre manière. Par exemple, si vous souhaitez "enregistrer" le stdin actuel et rediriger temporairement le stdin ailleurs puis le restaurer plus tard, vous pouvez faire quelque chose comme:

exec 4<&0
exec < /some/file
#process
exec 0<&4 4<&- # restore stdin and close our duplicate

Ce script aurait donc un 4descripteur de fichier disponible au moins pendant un certain temps. Cela pourrait être tout ce qui n'est pas utilisé (eh bien, il y a une limite au nombre de fichiers qu'un processus peut avoir ouvert, mais tout ce qui est dans cette limite).

Vous pouvez voir quels descripteurs de fichiers un processus a ouverts et où ils sont ouverts en regardant /proc/<pid>/fd. Cela montre tous les descripteurs de fichiers ouverts pour ce processus <pid>et les fichiers auxquels ils sont associés.

Eric Renouf
la source
0

Tout processus obtient des nombres entiers comme descripteurs de fichier, où il y en a trois réservés dans POSIX: 0 est stdin, 1 est stdout et 2 est stderr. Tous les autres fichiers se verront attribuer des numéros supplémentaires. Vous pouvez le vérifier facilement avec ce programme, l'enregistrer sous fdtest.c , afin qu'il ouvre son propre code de programme pendant l'exécution:

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main()
{
    int fd = open("fdtest.c", O_RDONLY);
    printf("%d\n", fd);
    close(fd);
    return 0;
}

Compilez-le:

gcc fdtest.c -o fdtest

Exécuter:

./fdtest

La sortie que vous obtiendrez ressemble à ceci:

3

... qui est le numéro du descripteur de fichier du fichier référencé par la variable fd.

rexkogitans
la source