Como o padrão “(cmd)” funciona no bash? [duplicado]

11

No bash, eu uso argumentos parecidos com

paste <(cat file1 | sort) <(cat file2 | sort)

ou

comm <(cat file1 | sort) <(cat file2 | sort)

Quando eu verifico man comm ou man paste , a documentação diz que os argumentos são realmente FILES.

Pergunta:

  1. Os arquivos temporários intermediários são criados (no sistema de arquivos TEMP ou em outro lugar no disco mais lento) para <(cat file1 | sort) e <(cat file2 | sort) ?

  2. Qual é o nome dessa <( ) magic? (para procurar sua documentação)

  3. É específico para bater ou funciona em outros shells?

por Thamme Gowda 24.05.2018 / 20:28

2 respostas

18

Isso é chamado de substituição de processo.

3.5.6 Substituição de processos

Process substitution allows a process’s input or output to be referred to using a filename.

The process list is run asynchronously, and its input or output appears as a filename. This filename is passed as an argument to the current command as the result of the expansion. If the >(list) form is used, writing to the file will provide input for list. If the <(list) form is used, the file passed as an argument should be read to obtain the output of list. Note that no space may appear between the < or > and the left parenthesis, otherwise the construct would be interpreted as a redirection. Process substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of naming open files.

Não é apenas uma coisa básica como originalmente apareceu no ksh, mas não está no padrão posix.

Under the hood, process substitution has two implementations. On systems which support /dev/fd (most Unix-like systems) it works by calling the pipe() system call, which returns a file descriptor $fd for a new anonymous pipe, then creating the string /dev/fd/$fd, and substitutes that on the command line. On systems without /dev/fd support, it calls mkfifo with a new temporary filename to create a named pipe, and substitutes this filename on the command line.

    
por 24.05.2018 / 20:30
7

Você pode pensar em <( somecommand ) como o nome do arquivo de um arquivo temporário que contém a saída de somecommand . Em outras palavras,

utility < <( somecommand )

é um atalho para

somecommand >tempfile
utility <tempfile
rm -f tempfile

e

utility <( somecommand )

é um atalho para

somecommand >tempfile
utility tempfile  # notice the lack of redirection here (utility expected to read from "tempfile")
rm -f tempfile

Da mesma forma, >( somecommand ) pode ser considerado como o nome do arquivo de um arquivo temporário que será alimentado em somecommand em sua entrada padrão. Em outras palavras,

utility > >( somecommand )

é um atalho para

utility >tempfile
somecommand <tempfile
rm -f tempfile

e

utility >( somecommand )

poderia ser um atalho para

mkfifo temppipe
somecommand <temppipe &
utility temppipe  # utility is expected to write to "temppipe"
rm -f temppipe

(ou algo similar)

    
por 24.05.2018 / 22:06