Primeiros dados escritos no pipeline (é consistente)

2

Se eu tiver esse canal:

echo "bar" | nc localhost 6969 < <(echo "foo")

"foo" sempre será gravado no soquete tcp antes de "bar"? Existe alguma precedência consistente?

    
por Alexander Mills 22.04.2018 / 10:48

3 respostas

3

Em

cmd1 | cmd2

cmd1 e cmd2 são iniciados em paralelo com o stdout de cmd1 conectado à extremidade de gravação de um pipe (ou socketpair em ksh93), e o stdin de cmd2 conectado à outra extremidade desse tubo.

Em:

cmd < file

cmd é iniciado com o stdin de cmd aberto no file .

Então você pode ver que

cmd1 | cmd2 < file

conflitos; você tem que escolher se o stdin de cmd2 é o canal de cmd1 ou o file .

Acima, na maioria dos shells, o <file tem precedência quando o redirecionamento é feito após (o shell inicia 2 processos com o pipe entre eles, e então interpreta cada um dos comandos, incluindo redirecionamentos dentro de cada um deles de forma independente)

Isso significa que o stdin de cmd2 será file e o canal echo que está gravando não terá leitor (um canal quebrado). Portanto, no seu caso, bar nunca chegará a nc e o processo que estiver executando echo bar poderá até ser morto se gravar bar depois que o outro processo abrir o arquivo.

Em zsh , no entanto, com a opção multios ativada (e ativada por padrão), zsh detecta que você está tentando redirecionar o mesmo descritor de arquivo (aqui 0, stdin) duas vezes e o leva que você queria que os dados de ambas as fontes fossem enviados para cmd2 , então, em vez de tornar cmd2 'stdin the pipe' de cmd1 ou file , ele realmente iniciará um alimentador < / em> processo que lê os dados de ambas as fontes e os envia (um após o outro, via outro canal) para cmd2 .

cmd1 < <(cmd2)

é apenas um caso de cmd1 < file onde file é um pipe nomeado (ou algo que se comporta como um pipe nomeado) com cmd2 escrito na outra extremidade, mas de outra forma não é muito diferente.

Portavelmente, se você quiser enviar a saída de dois comandos, ou enviar a saída de um comando e o conteúdo de um arquivo para algum comando, você usaria:

{
  cmd1
  cmd2
} | cmd3

Ou:

{
  cmd1
  cat < file
} | cmd2

Então, aqui:

{
  echo bar
  echo foo
} | nc localhost 6969
    
por 23.04.2018 / 11:08
3

O redirecionamento dos dados canalizados do primeiro echo para nc é substituído pelo redirecionamento da substituição do processo. Isso significa que nc só verá a entrada da substituição do processo, ou seja, a string foo .

Mais geralmente, em

command1 | command2 <data

command2 nunca lerá a saída de command1 .

Para que nc leiam as duas strings, combine com elas para serem entregues juntas, seja com

{ echo "foo"; echo "bar"; } | nc localhost 6969

ou

nc localhost 6969 < <( echo "foo"; echo "bar" )
    
por 22.04.2018 / 11:09
0

Eh por algum motivo parece complicado. Talvez você possa escrever algo em C, mas isso resolve o problema usando node.js:

#!/usr/bin/env node
'use strict';

const msg = process.argv[2] || process.env.ql_message;

if(!msg){
  console.error('quicklock: no message defined in ql_init_message.');
  process.exit(1);
}

console.log(msg);
process.stdin.resume().pipe(process.stdout);

na linha de comando você usa assim:

echo "bar" | initial_message "foo" | nc localhost 6969;

initial_message está apenas registrando uma coisa no stdout, depois apenas enviando stdin para stdout como uma passagem.

E neste caso eu def assumiria "foo" sempre seria escrito antes de "bar".

    
por 22.04.2018 / 11:02

Tags