Como criar entrada mesclada (stdin) para um programa

6

Considere esse roteiro:

echo a
echo b
echo c

Ele produzirá 3 linhas e agora posso executá-lo assim:

abc_script | real_program

real_program irá receber em sua entrada os 3 arquivos. No entanto, há um problema para um usuário, em vez de apenas chamar abc_script , ele precisa se lembrar de redirecionar a saída para o real_program .

Então, como mover esse redirecionamento para o script? Algo parecido com isto (o script):

echo a | echo b | echo c | real_program

Isso não funciona, é apenas uma ilustração do que eu gostaria de fazer - ocultar chamadas de real_program dentro do script.

Para o registro: no meu caso, a entrada consiste em algum arquivo, linhas extras adicionais. Então eu tenho:

cat $input_file
echo $extra_line

Não apenas a, b, c.

    
por greenoldman 07.07.2013 / 17:14

3 respostas

10

Assim:

( echo a
  echo b
  echo c ) | real_program

Isso executa os três comandos echo em um subshell e canaliza a saída do subshell para o script.

Subshells são açúcares sintáticos para bash -c 'echo a; echo b; echo c' | real_program .

    
por 07.07.2013 / 17:18
2

Outra maneira de fazer isso seria

echo -e "$(cat $input_file)\n$extra_line" | real_program
    
por 07.07.2013 / 17:27
2

Uma terceira maneira, que funciona pelo menos com o GNU bash 4.2.37 e deve funcionar com qualquer bash recente e possivelmente com outras shells (não sei como geralmente suportado <() é), é redirecionar a entrada de um comando .

$ echo hello > test
$ echo my > test
$ echo beautiful > test
$ cat <(cat test; echo world)
hello
my
beautiful
world
$

A idéia é criar primeiro o arquivo e, em seguida, lançar cat redirecionando seu stdin da saída da sequência de comandos cat test; echo world . Como visto na saída, essa entrada se torna a concatenação da saída de todos os comandos de redirecionamento de entrada.

Uma maneira alternativa de expressar a mesma coisa, que pode ser mais portável, é simplesmente reescrevê-la como um pipe de subshell simples em um comando:

(cat test; echo world) | cat

Note que os comandos são executados sequencialmente, mas sua saída se torna um único fluxo na entrada do comando externo ou próximo. Assim, enquanto o cat externo no exemplo acima não vê nenhum EOF ou algo assim, se invocar os comandos internos for caro de alguma forma, você pagará esse preço várias vezes. Eu duvido que haja alguma maneira de contornar isso.

    
por 07.07.2013 / 20:35

Tags