como emular a substituição do processo no Dash

11

Em bash , posso usar a substituição de processos e tratar a saída de um processo como se fosse um arquivo salvo em disco:

$ echo <(ls)
/dev/fd/63

$ ls -lAhF <(ls)
lr-x------ 1 root root 64 Sep 17 12:55 /dev/fd/63 -> pipe:[1652825]

infelizmente, a substituição de processo não é suportada em dash .

Qual seria a melhor maneira de emular process substitution em traço?

Eu não quero salvar a saída como um arquivo temporário em algum lugar ( /tmp/ ) e, em seguida, tenho que excluí-lo. Existe uma maneira alternativa?

    
por Martin Vegter 17.09.2016 / 13:02

1 resposta

7

Você pode reproduzir o que a casca faz sob o capô, fazendo o encanamento manualmente. Se o seu sistema tiver /dev/fd/NNN entradas, você pode usar o embaralhamento do descritor de arquivo: você pode traduzir

main_command <(produce_arg1) <(produce_arg2) >(consume_arg3) >(consume_arg4)

para

{ produce_arg1 |
  { produce_arg2 |
    { main_command /dev/fd5 /dev/fd6 /dev/fd3 /dev/fd4 </dev/fd/8 >/dev/fd/9; } 5<&0 3>&1 |
    consume_arg3; } 6<&0 4>&1; |
  consume_arg4; } 8<&0 9>&1

Eu mostrei um exemplo mais complexo para ilustrar várias entradas e saídas. Se você não precisa ler a entrada padrão, e a única razão pela qual você está usando a substituição do processo é que o comando requer um nome de arquivo explícito, você pode simplesmente usar /dev/stdin :

main_command <(produce_arg1)
produce_arg1 | main_command /dev/stdin

Sem /dev/fd/NNN , você precisa usar um canal nomeado . Um pipe nomeado é uma entrada de diretório, então você precisa criar um arquivo temporário em algum lugar, mas esse arquivo é apenas um nome, ele não contém nenhum dado.

tmp=$(mktemp -d)
mkfifo "$tmp/f1" "$tmp/f2" "$tmp/f3" "$tmp/f4"
produce_arg1 >"$tmp/f1" &
produce_arg2 >"$tmp/f2" &
consume_arg3 <"$tmp/f3" &
consume_arg4 <"$tmp/f4" &
main_command "$tmp/f1" "$tmp/f2" "$tmp/f3" "$tmp/f4"
rm -r "$tmp"
    
por 19.09.2016 / 00:51