Por que tempos embutidos não funcionam no pipeline?

3

Tenho o seguinte script de amostra:

#!/usr/bin/env bash
sleep 5
printf "times cmd: "
times
printf "pipeline: "
times | ( read user sys; echo $user; )
printf "head: "
times | head -n1
printf "times cmd again: "
times

com a seguinte saída:

$ ./test.sh 
times cmd: 0m0.003s 0m0.005s
0m0.001s 0m0.001s
pipeline: 0m0.000s
head: 0m0.000s 0m0.000s
times cmd again: 0m0.003s 0m0.006s
0m0.003s 0m0.004s

A pergunta é por que o comando times redefine o tempo quando usado com um pipeline? Existe alguma maneira de evitá-lo, a fim de analisar o valor?

    
por kenorb 17.01.2016 / 20:06

2 respostas

3

Dentro de um pipeline, todos os comandos são executados em um subshell. times informa o tempo gasto pelo shell e seus subshells, mas não pelo shell pai.

Você pode tentar a substituição do processo:

times > >( head -n1 )
times > >( read user sys ; echo $user )
    
por 17.01.2016 / 20:32
0

É uma questão de qual casca estamos falando.
Neste shell, eu recebo:

$ times
0m9.805s 0m3.372s
39m29.072s 0m15.537s

Porque está funcionando há algum tempo.
No entanto, um sub-shell reportará zero:

$ ( times )
0m0.000s 0m0.000s
0m0.000s 0m0.000s

E, como um pipeline é executado em um sub-shell para cada parte dele:

$  sleep 10 | times
0m0.000s 0m0.000s
0m0.000s 0m0.000s

Se você executar o comando acima, deverá ver a saída times imediatamente (pois ela não depende do canal) e o prompt do shell retornará 10 segundos depois.

Solução alternativa?

Permaneça no shell "this":

$ times > >(read user sys; echo "$user") 

Então, por que você precisa de tempo? Poderia time ou o mais poderoso /usr/bin/time funcionar para você?

Tempo de uso:

$ TIMEFORMAT="%R;%U;%S"; time { sleep 1; }
1.001;0.000;0.000
$ TIMEFORMAT="%U"; time { sleep 1; }         #### If you only want user.
0.000

Coloque vários processos entre chaves:

$ time { wc /etc/hosts; sleep 2; }
 21 115 327 /etc/hosts

real    0m2.003s
user    0m0.000s
sys     0m0.000s

Use o time externo mais poderoso (infelizmente só funciona em arquivos executáveis externos):

$ /usr/bin/time wc /etc/hosts
 21 115 327 /etc/hosts
0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 534maxresident)k
0inputs+0outputs (0major+109minor)pagefaults 0swaps
    
por 17.01.2016 / 23:08