redirecionamento de saída do bash - qual é a diferença entre e &, redirecionando e duplicando?

3

Estou tentando entender o redirecionamento de saída, mas estou lutando. Eu não acho que eu realmente entendi as diferenças.

1 > file        # -  redirect stdout to file (override mode)
1 >> file       # -  redirect stdout to file (append mode)
2 > 1           # 1) would that also redirect stderr to stdout, replacing stdout?
2 >> 1          # 2) would this redirect stderr to stdout (appending to it,
                #    i.e. haivng both sent to stdout?)
1>&9            # -  duplicates stdout to file descriptor (pointer) 9 
                # 3) what's the difference of 2>&1 to a 2 >> 1? Does >> only run at the end
                #     of output?
echo foo > file # -  redirects output to file (override mode)
>file 2>&1      # -  duplicates stderr to stdout, then redirects to file in override mode 
                # 4) why is this giving me stdout, too, when the syntax is 2>&1, 
                #    i.e. duplicate stderr into stdout - not merge 2 into 1?

Eu estou supondo que o e comercial & significa duplicado, ao contrário do redirecionamento. Mas qual é a diferença de redirecionar a para b ( a permanecerá inalterado?) Para duplicar a para b ( a e b serão iguais?)? 2>&1 parece efetivamente redirecionar e mesclar 2 em 1 , ou seja, o que teria entrado em 2 agora está em 1 , mas somente em 1 ... por quê?

Estou tão confuso ...

    
por Christian 31.08.2016 / 11:57

2 respostas

4

Primeiro, qualquer coisa após > ou >> é um nome de arquivo; então > 1 grava em um arquivo chamado 1 .

Os números nos outros formulários fornecidos no seu exemplo são descritores de arquivos. Por padrão, os programas começam com os descritores de arquivo 0 (entrada padrão), 1 (saída padrão) e 2 (erro padrão) conectados; quando você inicia um programa a partir de um shell interativo, eles são conectados à entrada e à saída do terminal (você pode vê-los executando ls -l /proc/$$/fd no Linux).

Especificar um número antes de > , >> ou >& especifica o descritor de arquivo que você deseja manipular; o número deve estar bem na frente do símbolo > . Assim

echo Example 2> stderr

imprimirá "Exemplo" e criará um arquivo stderr vazio (que conterá qualquer coisa enviada para o erro padrão).

Você pode pensar em descritores de arquivos como entradas em uma tabela, apontando para arquivos; assim, por padrão:

  • 0 pontos para /dev/tty
  • 1 pontos para /dev/tty
  • 2 pontos para /dev/tty

Especificar 1> file (ou simplesmente > file ) atualiza o descritor de arquivo 1 para apontar para file , aberto no modo de truncamento (portanto, seu conteúdo é substituído). A especificação de 2> 1 atualiza o descritor de arquivo 2 para apontar para um arquivo chamado 1 , aberto no modo de truncamento.

A duplicação de descritores de arquivos usando >& (ou &> , que é a forma preferida) simplesmente atualiza um descritor de arquivo para apontar para o que o outro está apontando. No seu último exemplo, > file atualiza o descritor de arquivo 1:

  • 0 pontos para /dev/tty
  • 1 pontos para file
  • 2 pontos para /dev/tty

e, em seguida, 2>&1 atualiza o descritor de arquivo 2:

  • 0 pontos para /dev/tty
  • 1 pontos para file
  • 2 pontos para file

(o pedido é significativo: > file 2>&1 produz o acima, 2>&1 > file só acabaria redirecionando o descritor de arquivo 1).

O formulário 1>&9 só funciona se o descritor de arquivo 9 tiver sido aberto, por exemplo. , copiando o descritor de arquivo 1 para ele ( 9>&1 ) ou abrindo um arquivo ( 9> file ). Esse tipo de construção pode ser útil para acompanhar o conteúdo original dos descritores de arquivos ao redirecionar; Assim, em um script, você pode copiar 1 e 2 com segurança, redirecionar a saída e o erro padrão para qualquer finalidade que você precisar e, em seguida, restaurá-los ...

O manual do Bash contém todos os detalhes.

    
por 31.08.2016 / 12:24
1

Você teve algumas suposições erradas.

A sintaxe geral para o redirecionamento é:

[n]redirection-operator word

onde n é um número decimal indica um descritor de arquivo. Observe que não há espaço entre n e redirection-operator .

Para redirecionar a saída padrão para o arquivo, você precisa:

> file

ou:

1> file

1 > file significa executar o comando 1 e redirecioná-lo para file ou, explicitamente, o mesmo que:

1 1> file

O mesmo para o erro padrão 2> file e >> operator.

Para duplicar um descritor de arquivo, você usará:

  • [n]<&word para o descritor de arquivo de entrada
  • [n]>&word para o descritor de arquivo de saída
  • [n]<>word para abrir o descritor de arquivos para leitura e gravação

Todos os itens acima são sintaxe padrão, o que funcionará se você usar #!/bin/sh em seu script.

Alguns shells têm suas próprias extensões, como bash com >& para redirecionar o erro padrão e o padrão, ksh93 com <>; para truncar o deslocamento na conclusão do comando.

Agora, você pode ver as diferenças deles.

O operador duplicando funciona apenas com descritores de arquivos, enquanto o operador redirecionando só funciona com arquivos (que são mapeados para descritores de arquivo sob o capô).

    
por 31.08.2016 / 12:27