Redirecionamento de saída do programa

11

Ao tentar redirecionar a saída do programa com a sintaxe "algum número maior que" (por exemplo foo 2> myfile), quais são os números possíveis aqui e o que eles representam?

Eu acredito que 1 é /dev/stdout, 2 é /dev/stderr. Que tal 5 e 6? Existe 3, 4 ou algum número maior que 6?

Aluno de Fermat
fonte
Consulte também Quando você usaria um descritor de arquivo adicional?
Gilles 'SO- stop be evil'

Respostas:

11

Esse suposto programa gravará no número do descritor de arquivo que você especificou. considere o seguinte programa 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) ;
}

compile

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

agora uma corrida simples

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

nenhum arquivo para 5, então nenhum byte escreveu.

próxima tentativa:

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

Consigo obter uma saída ao especificar um arquivo e um descritor de arquivo (por exemplo 5>u).

Na prática, a menos que você tenha escrito um programa engraçado como o descrito acima, é improvável que você colete dados usando 5>foo.

no script shell, construir usando <() é mais útil:

 diff <( cmd -par 1 ) <(cmd -par 2)
Archemar
fonte
write()retorna ssize_t, não int.
Andrew Henle
Esse não é o ponto principal da pergunta, também há um retorno para a função printf.
Archemar 14/10
Não usar um valor retornado é muito diferente de usar o tipo errado .
Andrew Henle
editado Eu não vejo nenhuma mudança na saída tho ...
Archemar
10

Os números representam descritores de arquivo (identificadores para arquivos que foram abertos).

O shell geralmente tem 3 definido automaticamente,

0 - stdin 1 - stdout 2 - stderr

Mas outros arquivos podem ser abertos e os números aumentam.

X Tian
fonte
7

Esses números são descritores de arquivos . Como você observou, existem vários que são criados automaticamente. Quando outros arquivos ou coisas semelhantes a arquivos são abertos, eles recebem outros números.

Os números usados ​​em qualquer programa específico dependem de quais arquivos foram abertos por esse programa ou usados ​​de outra forma. Por exemplo, se você deseja "salvar" o stdin atual e redirecionar temporariamente o stdin de outro lugar, em seguida, restaurá-lo mais tarde, você pode fazer algo como:

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

Portanto, esse script teria um 4descritor de arquivo disponível pelo menos por algum tempo. Esse 4 pode ser qualquer coisa que não esteja em uso (bem, há um limite para quantos arquivos um processo pode abrir, mas qualquer coisa dentro desse limite).

Você pode ver para quais descritores de arquivo um processo foi aberto e para onde eles estão abertos olhando /proc/<pid>/fd. Isso mostra todos os descritores de arquivos abertos para esse processo <pid>e com quais arquivos esses estão associados.

Eric Renouf
fonte
0

Qualquer processo obtém números inteiros como descritores de arquivo, onde existem três reservados no POSIX: 0 é stdin, 1 é stdout e 2 é stderr. Quaisquer outros arquivos receberão mais números. Você pode verificá-lo facilmente com este programa, salvá-lo como fdtest.c , para que ele abra seu próprio código de programa durante o tempo de execução:

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

Compile-o:

gcc fdtest.c -o fdtest

Executá-lo:

./fdtest

A saída que você obterá é mais ou menos assim:

3

... que é o número do descritor do arquivo referido pela variável de arquivo fd.

rexkogitans
fonte