Reindirizzamento dell'output del programma


11

Quando si tenta di reindirizzare l'output del programma con la sintassi "un numero maggiore di" (ad es. foo 2> myfile), Quali sono i possibili numeri qui e cosa rappresentano?

Credo che 1 sia /dev/stdout, 2 sia /dev/stderr. Che dire di 5 e 6? C'è 3, 4 o un numero maggiore di 6?


Risposte:


11

Questo presunto programma scriverà sul numero del descrittore di file specificato. considera il seguente programma Hello World:

#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) ;
}

compilarlo

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

ora una corsa semplice

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

nessun file per 5, quindi nessun byte scritto.

prossimo tentativo:

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

Riesco a ottenere un output specificando un file e un descrittore di file (ad es 5>u.).

In pratica, a meno che tu non abbia scritto un programma così divertente come sopra, è improbabile che tu raccolga dati usando 5>foo.

nello script di shell, il costrutto con <() è più utile:

 diff <( cmd -par 1 ) <(cmd -par 2)

write()ritorna ssize_t, no int.
Andrew Henle,

Questo non è il punto principale della domanda, c'è anche un ritorno per la funzione printf.
Archemar,

Non utilizzare un valore restituito è molto diverso dall'utilizzo del tipo errato .
Andrew Henle,

a cura non vedo alcun cambiamento nell'output ...
Archemar,

10

I numeri rappresentano i descrittori di file (gestisce i file che sono stati aperti).

La shell di solito ne ha 3 impostati automaticamente,

0 - stdin 1 - stdout 2 - stderr

Ma è possibile aprire altri file e aumentare i numeri.


7

Quei numeri sono descrittori di file . Come hai notato, ce ne sono diversi che vengono creati automaticamente. Man mano che vengono aperti altri file o cose simili a file, otterranno altri numeri.

I numeri utilizzati in un determinato programma dipendono da quali file sono stati aperti da quel programma o utilizzati in altro modo. Ad esempio, se si desidera "salvare" lo stdin corrente e reindirizzare temporaneamente lo stdin da altrove, quindi ripristinarlo in un secondo momento, è possibile fare qualcosa del tipo:

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

Quindi questo script avrebbe un 4descrittore di file disponibile almeno per qualche tempo. Quel 4 potrebbe essere tutto ciò che non è in uso (beh, c'è un limite per quanti file può essere aperto un processo, ma qualsiasi cosa all'interno di quel limite).

Puoi vedere quali descrittori di file hanno aperto un processo e dove sono aperti guardando /proc/<pid>/fd. Ciò mostra tutti i descrittori di file aperti per quel processo <pid>e quali file sono associati.


0

Qualsiasi processo ottiene numeri interi come descrittori di file, dove ce ne sono tre riservati in POSIX: 0 è stdin, 1 è stdout e 2 è stderr. A tutti gli altri file verranno assegnati ulteriori numeri. Puoi controllarlo facilmente con questo programma, salvarlo come fdtest.c , in modo che apra il suo codice programma durante il runtime:

#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;
}

Compilalo:

gcc fdtest.c -o fdtest

Eseguirlo:

./fdtest

L'output che otterrai è qualcosa del genere:

3

... che è il numero del descrittore di file del file a cui fa riferimento la variabile fd.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.