<(cmd)
é um recurso ksh
encontrado também em zsh
e bash
chamado substituição de processo .
Em sistemas que suportam /dev/fd/n
ou /proc/self/fd/n
, ele é implementado com pipes e quando não com pipes nomeados temporários. Em qualquer caso, é uma forma de pipe que é um mecanismo de comunicação entre processos.
cmd1 <(cmd2)
Pode ser escrito (com canais normais):
{ cmd2 3<&- | 3<&0 <&3 3<&- cmd1 /dev/fd/3; } 3<&0
Ou (com pipes nomeados):
mkfifo /tmp/named_pipe
cmd2 > /tmp/named_pipe & cmd1 /tmp/named_pipe
Ou seja, ambos os comandos são iniciados simultaneamente e se comunicam com um pipe. Normalmente, você usaria cmd2 | cmd1
para isso, mas a substituição do processo geralmente é para os casos em que cmd1
só pode receber entrada de um nome de arquivo e não da entrada padrão ou quando mais de uma entrada é necessária, como em diff <(cmd1) <(cmd2)
. / p>
Não há nenhum rlimit que o afete além dos gerais, como o número de processos, o tempo de CPU ou a memória.
O PIPEBUF relatado por algumas implementações de ulimit
como bash
e algumas implementações de ksh
não é um rlimit, mas o tamanho máximo para o qual uma gravação em um pipe é garantida como atômica é irrelevante aqui. O tamanho do canal em si (64kB no Linux, conforme relatado por @ dsmsk80) não é realmente um limite em si. Apenas diz que é tanto que cmd2
pode gravar no pipe mesmo depois que cmd1
parou de ler a partir dele.
Há uma limitação, no entanto, em que cmd1
só pode ler desse arquivo. Por ser um pipe, ele não pode gravar no arquivo ou procurar no arquivo.
zsh
tem uma terceira forma de substituição de comando usando arquivos temporários comuns:
cmd1 =(cmd2)
chama cmd1
com um arquivo temporário que contém a saída de cmd2
. Nesse caso, cmd1
é executado após cmd2 em vez de concorrentemente. O limite do tamanho dos arquivos pode ser alcançado lá.
Não conheço nenhum shell que esteja implementando um operador <<<(...)
. No entanto, há um operador <<<
em zsh
(inspirado na mesma operadora na porta Unix de rc
) também encontrado nas versões recentes de ksh93
e bash
. É uma variação do operador <<
heredoc chamado herestring.
Em:
cmd <<< something
Qual é o mesmo que o padrão:
cmd << EOF
something
EOF
O shell cria um arquivo temporário com something\n
como o conteúdo e alimenta isso como entrada padrão para um novo processo, desvincula esse arquivo e executa cmd
nesse novo processo. Novamente, esse é um arquivo regular para que o rlimit no tamanho máximo de um arquivo seja atingido.
Agora, você pode combinar o operador <<<
com $(...)
(substituição de comando) para emular de alguma forma o operador zsh
=(...)
em bash
e ksh93
:
cmd1 <<<"$(cmd2)"
Executaria cmd2
com stdout redirecionado para um canal. Na outra extremidade do canal, o shell lê a saída de cmd2
e armazena menos os caracteres de nova linha à direita e com um caractere de nova linha adicionado em um arquivo temporário e chama cmd1
com esse arquivo temporário aberto para leitura como stdin ( note que há outra limitação em que não funcionará se cmd2
output contiver caracteres NUL).
Para ser como =(...)
, você teria que escrevê-lo:
cmd1 /dev/fd/3 3<<<"$(cmd3)"
Observe que o shell precisa ler toda a saída de cmd3 na memória antes de gravá-la no arquivo temporário, portanto, além do tamanho máximo do arquivo, você também pode atingir o limite de uso de memória.