Um pipe, assim como qualquer arquivo, é um fluxo de texto (mais precisamente, um fluxo de bytes). Os blocos básicos de construção do Unix tendem a ser simples. As interações entre processos são baseadas principalmente em dados não estruturados. O sistema operacional não fornece um canal de comunicação com vários fluxos rotulados por um nome de arquivo. Se os programas precisarem disso, eles precisarão organizar seus próprios - e tubos separados, um para cada fluxo, seriam a implementação mais natural.
Se program2
e program3
agirem independentemente em cada fluxo, execute uma cópia deles para cada um dos arquivos. Para executá-los sequencialmente, use um loop de shell. Como o pipe, o loop é um dos recursos do shell para unir programas. Para informar a program3
onde colocar a saída, a interface usual é para program3
gravar em sua saída padrão e usar uma construção de redirecionamento no shell para direcionar a saída para um arquivo. O shell fornece algumas construções básicas de manipulação de strings para construir nomes de arquivos; aqui é apenas concatenação.
for x in *.txt; do
program1 "$x" | program2 | program3 >"folder/$x"
done
Se os programas são leves no IO, mas exigem muita CPU e você tem várias CPUs, você pode querer executá-las em paralelo. Com ferramentas GNU bastante recentes, você pode usar xargs
para executar programas em paralelo. Passe o número de CPU no seu sistema como o argumento para -P
. Como o comando que o xargs
precisa executar é um pipeline, você precisa invocar um shell.
find -maxdepth 1 -name '*.txt' -print0 |
xargs -0 -n 1 -P 4 sh -c 'program1 "$1" | program2 | program3 >"$0/$1"' "folder"
Você pode usar GNU paralelo ao invés de xargs para determinar o número de CPUs no seu sistema automaticamente.
parallel sh -c 'program1 "$1" | program2 | program3 >"$0/$1"' "folder" ::: *.txt
Se você precisar de uma única instância de program2
e program3
para processar vários arquivos, será necessário criar esses programas com uma interface personalizada para receber vários canais como entrada. Não há maneira padrão de fazer isso. Um método é permitir que eles invoquem o programa que fornece sua entrada. Seria semelhante à maneira como xargs
e parallel
são informados sobre qual programa invocar para processar sua saída.