Redirecionamento usando descritores de arquivo - exemplo específico [duplicado]

0

Estou lendo esta documentação , que fornece os seguintes exemplos sobre redirecionamento e descritores de arquivo .

ls > dirlist 2>&1

will direct both standard output and standard error to the file dirlist, while the command

ls 2>&1 > dirlist

will only direct standard output to dirlist. This can be a useful option for programmers.

Esses exemplos são errados? Parece-me que o exemplo segundo "direcionará a saída padrão e o erro padrão para a lista de arquivos", enquanto o primeiro "direcionará a saída padrão para a dirlist".

Se eu estiver errado sobre isso (... provavelmente ...) alguém pode explicar claramente a lógica desses dois exemplos?

    
por penname 22.11.2016 / 02:42

2 respostas

1

Antes de tudo, você precisa entender a sintaxe n>&m . esta é uma operação de duplicação, significando a cópia m para n. confira a seção "3.6.8 Duplicando descritores de arquivo" .

Eu tive a mesma dúvida que você quando estudei o artigo. Então eu posso tentar explicar para você:

ls > dirlist 2>&1 

com o comando acima, você primeiro redireciona a saída para a lista por > dirlist . 2>&1 significa o descritor de arquivo de cópia de 1 a 2, em outras palavras, faz de fd2 uma cópia de fd1. Agora o fd1 já está apontado para o dirlist, fazendo do fd2 uma cópia do fd1 significa que o fd2 também aponta para o dirlist. Como resultado, fd1- > dirlist, fd2- > dirlist.

ls 2>&1 > dirlist   

com isto, você primeiro faz a fd2 uma cópia do fd1 que ainda é o terminal, então fd2- > terminal. então você redireciona fd1 para dirlist. como resultado, fd2 - > terminal, fd1- > dirlist.

    
por 22.11.2016 / 03:18
0

As rotas são processadas da esquerda para a direita.

ls > dirlist 2>&1

faz o shell que eventualmente se tornará ls, faça as seguintes chamadas de sistema (verificação de erro omitida para brevidade).

/* Handle > dirlist */
int temp_fd = open("dirlist",O_WR);  /* Open dirlist for output */
dup2(temp_fd, 1); /* Make file descriptor 1 (stdout) point to dirlist */
close(temp_fd);  /* Don't need this other file descriptor for dirlist */
/* Handle 2>&1 */
dup2(1,2); /* Make fd 2 be a copy of fd 1, which points to dirlist */

Então, primeiro fd 1 é alterado e, em seguida, fd 2 é alterado.

Por outro lado, ls 2 > & 1 > dirlist faz

/* Handle 2>&1 */
dup2(1,2); /* Make fd 2 be a copy of fd 1, the original stdout */
/* Handle > dirlist */
int temp_fd = open("dirlist",O_WR);  /* Open dirlist for output */
dup2(temp_fd, 1); /* Make file descriptor 1 (stdout) point to dirlist */
close(temp_fd);  /* Don't need this other file descriptor for dirlist */

Uma maneira diferente de ver isso é apenas atribuições. Originalmente fd1 = initial_stdout, então

/* ls > dirlist 2>&1 */
fd1=to_dirlist
fd2=fd1 (i.e. to_dirlist)

/* ls 2>&1 > dirlist */
fd2=fd1 (i.e. initial_stdout)
fd1=to_dirlist.

Ou você pode dizer copy by value em vez de copy by reference .

    
por 22.11.2016 / 06:24