Por que time ls | grep real
produz isso
real 0m0.002s
user 0m0.000s
sys 0m0.002s
em vez de apenas
real 0m0.002s
Se eu digitar
echo -e 'real\t0m0.002s\nuser\t0m0.000s\nsys\t0m0.002s\n' | grep real
Eu consigo o que espero, ou seja
real 0m0.002s
Eu descobri que isso funciona
(time ls) 2>&1 > /dev/null | grep real
O que esse comando faz?
Responder1
Por que time ls | grep real
não funciona como esperado.
time
é uma bash
palavra reservada e se comporta de maneira diferente de /usr/bin/time
.
Se a palavra reservada de tempo preceder um pipeline, o tempo decorrido, bem como o tempo do usuário e do sistema consumido por sua execução serão relatadosquando o pipeline termina.
Fontebash(1): GNU Bourne-Again SHell - página de manual do Linux
Além disso, time
as saídas para erro padrão e não para saída padrão.
Use o seguinte comando:
(time ls) 2>&1 >/dev/null | grep real
Notas:
O
(
e)
agrupa os comandostime
els
(para que esses comandos sejam avaliados primeiro)2>&1 >/dev/null
primeiro redireciona stderr para stdout (que é o canal) e depois redireciona stdout para/dev/null
.Então stderr vai para o cano e stdout não leva a lugar nenhum.
Leitura adicional
- Um índice AZ da linha de comando Bash para Linux- Uma excelente referência para todas as coisas relacionadas à linha de comando do Bash.
- colchetes- Usando parênteses para agrupar e expandir expressões.
- redirecionamento de sintaxe- Redirecionamento e Substituição de Processos.
- Manual de referência do Bash: redirecionamentos
- Tutorial ilustrado de redirecionamento [Bash Hackers Wiki]
Responder2
Sim, funciona, mas requer um pouco de redirecionamento de E/S :)
$ exec 3>&1 4>&2
{ time sleep 1 1>&3 2>&4; } 2>&1 |
grep 'real'
exec 3>&- 4>&-
Saída :
real 0m1,003s
LerPerguntas frequentes sobre bash nº 32eTutorial de redirecionamento de E/S
Uma maneira bem mais simples:
$ TIMEFORMAT=%R
$ time sleep 1
1,003
Responder3
Duas questões aqui.
Primeiro e mais importante, "time" envia sua saída para stderr (erro padrão) e não para stdout, para que não seja capturado por comandos normais de redirecionamento, a menos que você tome medidas especiais.
Segundo, time não é um programa normal, mas um comando especial integrado interpretado diretamente pelo shell (para shells como bash, csh, tcsh, etc.). Portanto, ele funciona de maneira não padrão e cronometra todo o resto da linha de comando (a menos que você esteja usando um shell muito incomum).
Então, para obter o resultado desejado (usando bash), você precisa usar:
(time ls) 2>&1 | grep real
Isso executará o "ls" em um subshell e cronometrará [(tempo ls)] , envie o erro padrão para a saída padrão[2>&1]e, em seguida, envie o padrão para "grep" [|grep].
A última parte que você usou ">?dev/null" descarta a saída normal do próprio comando ls, caso inclua a palavra "real".
Responder4
Parece que time
grava diretamente no console e não em stdout
, o que significa que a saída do comando ou pipeline não é afetada pela adição de time
.
Portanto, grep
nunca vê o relatório de tempo, que em qualquer caso é gerado após grep
a conclusão, já que todo o pipeline é cronometrado.