O macOS vem com uma versão muito antiga de bash
. Esse bug (que o descritor de arquivo para essa substituição de processo é fechado antes de chamar tee
nesse contexto) foi corrigido em versões mais novas. Você obteria o mesmo problema no Linux (com uma mensagem de erro diferente, pois /dev/fd/x
é implementado de forma diferente lá) com o bash 3.2 lá.
Aqui, você pode usar zsh
ou ksh93
. É uma boa idéia evitar bash
aqui mesmo assim como ele não espera por processos em substituições de processos (o zsh espera por eles, o ksh93 pode ser avisado para wait
para eles).
Note que, mesmo com a versão mais recente (4.4.12), bash
ainda tem alguns bugs, como:
$ bash -c 'eval cat <(echo test)'
test # OK but:
$ bash -c 'eval "echo foo;cat" <(echo test)'
foo
cat: /dev/fd/63: No such file or directory
$ bash -c 'eval f=<(echo test) "; cat \$f"'
cat: /dev/fd/63: No such file or directory
e alguns ainda são acionados por canais como:
$ cat file
echo "$1"
cat "$1"
$ bash -c 'source ./file <(echo test)'
/dev/fd/63
test # OK but:
$ cat file2
echo "$1" | wc -c
cat "$1"
$ bash -c 'source ./file2 <(echo test)'
11
cat: /dev/fd/63: No such file or directory
¹ bash fecha o descritor de arquivo assim que houver um pipeline. Um reprodutor mais curto:
$ bash -c 'f() { :; cat "$1"; }; f <(echo OK)'
OK
$ bash -c 'f() { :|:; cat "$1"; }; f <(echo test)'
cat: /dev/fd/63: No such file or directory