está funcionando.
As diferentes partes de um pipeline são executadas simultaneamente. A única coisa que sincroniza / serializa os processos no pipeline é IO, ou seja, um processo sendo gravado no próximo processo no pipeline e o próximo processo lendo o que o primeiro escreve. Além disso, eles estão executando independentemente um do outro.
Como não há leitura ou gravação acontecendo entre os processos em seu pipeline, o tempo gasto para executar o pipeline é o da chamada sleep
mais longa.
Você pode muito bem ter escrito
time ( foo.sh & bar.sh &; wait )
Terdon postou alguns exemplos de scripts levemente modificados no bate-papo :
#!/bin/sh
# This is "foo.sh"
echo 1; sleep 1
echo 2; sleep 1
echo 3; sleep 1
echo 4
e
#!/bin/sh
# This is "bar.sh"
sleep 2
while read line; do
echo "LL $line"
done
sleep 1
A consulta foi "por que time ( sh foo.sh | sh bar.sh )
retorna 4 segundos em vez de 3 + 3 = 6 segundos?"
Para ver o que está acontecendo, incluindo o tempo aproximado que cada comando é executado, pode-se fazer isso (a saída contém minhas anotações):
$ time ( env PS4='$SECONDS foo: ' sh -x foo.sh | PS4='$SECONDS bar: ' sh -x bar.sh )
0 bar: sleep 2
0 foo: echo 1 ; The output is buffered
0 foo: sleep 1
1 foo: echo 2 ; The output is buffered
1 foo: sleep 1
2 bar: read line ; "bar" wakes up and reads the two first echoes
2 bar: echo LL 1
LL 1
2 bar: read line
2 bar: echo LL 2
LL 2
2 bar: read line ; "bar" waits for more
2 foo: echo 3 ; "foo" wakes up from its second sleep
2 bar: echo LL 3
LL 3
2 bar: read line
2 foo: sleep 1
3 foo: echo 4 ; "foo" does the last echo and exits
3 bar: echo LL 4
LL 4
3 bar: read line ; "bar" fails to read more
3 bar: sleep 1 ; ... and goes to sleep for one second
real 0m4.14s
user 0m0.00s
sys 0m0.10s
Então, para concluir, o pipeline leva 4 segundos, não 6, devido ao buffer da saída das duas primeiras chamadas para echo
em foo.sh
.