foo
não sabe qual arquivo ler, ele (presumivelmente) apenas lê seu fluxo de entrada padrão. Esse fluxo de dados é conectado pelo shell ao fluxo de saída padrão do comando cat
. Esse "encanamento administrativo" é feito pelo shell quando ele inicia os dois processos (eles seriam executados simultaneamente).
No exemplo da pergunta, é cat
que abrirá o arquivo para leitura, lerá e passará os dados em sua saída padrão.
Você também pode perguntar "Como o cat
sabe onde gravar o resultado?" A resposta é que ele grava em seu fluxo de saída padrão, conectado pelo shell ao fluxo de entrada padrão do comando foo
. Da mesma forma, o fluxo de saída padrão do comando foo
é conectado ao terminal pelo shell, pois não há mais canalizações ou redirecionamentos para esse comando.
O canal que você mostra,
cat someFile | foo
é funcionalmente idêntico a
foo <somefile
Aqui eu deletei cat
, já que não é realmente necessário. O shell conectará o fluxo de entrada padrão de foo
ao arquivo fornecido, para que o efeito seja o mesmo ( foo
seria capaz de ler o conteúdo de somefile
de seu fluxo de entrada padrão).
Neste último comando, foo
ainda não sabe que lê dados provenientes de um arquivo chamado somefile
. Ele também não sabe que não está mais lendo a saída de cat
. Ele apenas lê seu fluxo de entrada padrão como antes.
Agora é o shell que abrirá o arquivo somefile
para leitura, mas o shell não lerá nada do arquivo, apenas conecte o fluxo de entrada padrão com o arquivo aberto para foo
ler. / p>
Note que não sabemos o que o comando foo
faz, se realmente qualquer coisa com seu fluxo de entrada padrão, ou se espera que um nome de arquivo seja lido em sua linha de comando. Esse tipo de informação estaria disponível no manual do programa foo
.
No caso em que foo
na verdade precisa que seja instruído a ler um arquivo específico, dando a ele um nome de caminho na linha de comando, você pode usar
foo somefile
Agora, foo
seria responsável pela abertura e leitura do arquivo.
Se o arquivo tiver que ser processado de alguma forma (supondo que " cat
" seja um processo mais complicado que realmente modifique os dados lidos de somefile
):
cat somefile >newfile
foo newfile
rm newfile
Ou seja, processe o arquivo e salve o resultado em um novo arquivo temporário e, em seguida, passe o nome do arquivo temporário para foo
. Em seguida, remova o arquivo temporário.
Ou com um shell que entende substituições de processo (como bash
):
foo <( cat somefile )
Aqui, o shell organizaria para que a saída de cat somefile
fosse gravada em um arquivo temporário (ou pipe nomeado, não importa realmente) e o nome do caminho desses dados seria inserido no lugar da substituição do processo %código%. <( ... )
abriria isso como seu arquivo para ler.
Neste exemplo final, foo
abriria o arquivo original e o leria enquanto cat
abriria qualquer nome de caminho que o shell lhe fornecesse (onde a saída de foo
fosse encontrada) e fosse lida a partir dele.