time
escreve para stderr
, então alguém poderia assumir que adicionar 2>&1
à linha de comando deve rotear sua saída para stdout
. Mas isso não funciona:
test@debian:~$ cat file
one two three four
test@debian:~$ time wc file > wc.out 2>&1
real 0m0.022s
user 0m0.000s
sys 0m0.000s
test@debian:~$ cat wc.out
1 4 19 file
Somente com parênteses funciona:
test@debian:~$ (time wc file) > wc.out 2>&1
test@debian:~$ cat wc.out
1 4 19 file
real 0m0.005s
user 0m0.000s
sys 0m0.000s
Por que os parênteses são necessários neste caso? Por que não é time wc
interpretado como um único comando?
io-redirection
shell-builtin
lobo-revo-gatos
fonte
fonte
time
da palavra-chave shell ou/usr/bin/time
. Pode haver vários conjuntos de descritores envolvidos aqui (o shell e os anexados a umtime
processo). E não vamos esquecer os implícitos no()
subshell. ( Esperando por um especialista do bash : p)Respostas:
Em
ksh
,bash
ezsh
,time
não é um comando (embutido ou não), é uma palavra reservada no idioma comofor
ouwhile
.É usado para cronometrar um pipeline 1 .
Dentro:
Você tem uma sintaxe especial que informa ao shell para executar essa linha de tubulação:
E relate estatísticas de tempo para isso.
Dentro:
É o mesmo, você está cronometrando o
cmd > output 2> error
comando e as estatísticas de cronometragem ainda continuam no stderr do shell.Você precisa:
Ou:
Para que o stderr do shell seja redirecionado para
timing-output
antes da construção da hora (novamente, não do comando ) ser usada (aqui para a horacmd > output 2> error 3>&-
).Você também pode executar essa
time
construção em um subshell que tenha seu stderr redirecionado:Mas esse subshell não é necessário aqui, você só precisa que o stderr seja redirecionado no momento em que a
time
construção é invocada.A maioria dos sistemas também possui um
time
comando. Você pode invocar essa desativando atime
palavra - chave. Tudo que você precisa fazer é citar essa palavra-chave de alguma forma, pois as palavras-chave são reconhecidas como tal apenas quando literais.Mas cuidado, o formato pode ser diferente e o stderr de ambos
time
ecmd
será mescladoerror-and-timing-output
.Além disso, o
time
comando, ao contrário datime
construção, não pode cronometrar pipelines ou comandos ou funções compostas ou embutidos no shell ...Se fosse um comando interno, ele poderá cronometrar invocações ou funções internas de função, mas não poderá cronometrar redirecionamentos, pipelines ou comandos compostos.
1 Observe que
bash
possui (o que pode ser considerado) um erro pelo qualtime (cmd) 2> file
(mas nãotime cmd | (cmd2) 2> file
por exemplo) redireciona a saída de temporização parafile
fonte
time
é uma palavra-chave, não um shell embutido.'time'
para obter o executável - mais prático do que escrever/usr/bin/time
(ou atécommand time
:-)).\time
.Não há nenhum comando chamado
time wc
,time
ewc
são separados palavra no escudo.Agora, geralmente existem dois programas separados nomeados
time
, um é a palavra-chave shell, outro é o comando externo . Em shells, quetime
é uma palavra-chave shell, quando você digitatime wc ...
, o shell usa sua palavra-chave emtime
vez do utilitário de tempo externo .Quando o shell usa a
time
palavra-chave, ele não precisa bifurcar () o novo processo, otime
padrão atual e o erro padrão não são alterados. A parte de redirecionamento em:afeta
wc
apenas.Quando você usa o comando composto
(list)
:o shell foi executado
time wc file
dentro de um subshell,(time wc file)
foi considerado um único comando e a parte de redirecionamento afeta sua saída e erro padrão, que agora incluem ambostime
ewc
.Você pode fazer o mesmo efeito, sem o custo de criar um novo processo usando outra forma de comando de agrupamento
{list;}
:Se você usa externo
time
, não enfrenta esse problema, porque ele foi executado em um novo processo:fonte
time
e/usr/bin/time
? Os executáveis estão sendo chamados funcionalmente iguais?Porque
time
você está executando o bash builtin. O Bash processa-o de maneira tão especial.Se você usar o
time
binário real , ele atuará exatamente da maneira que você espera:Embora a saída desse tempo seja um pouco diferente:
fonte
time cmd > output
vezes ocmd > output
comando etime foo | bar
vezesfoo | bar
.Não é
time
que escreve a informação da hora. O builtintime
faz com que o shell escreva isso após a conclusão do comando. Mas o redirecionamento afeta apenas o comando.No
(time ...)
caso, o redirecionamento é aplicado a todo o subshell.fonte
Como o tempo é incorporado ao shell, ele grava no stderr do shell , e não no stderr do comando.
Usar parênteses força todo o comando em um shell filho cujo stderr pode ser redirecionado.
o uso de colchetes produz um resultado semelhante sem realmente iniciar um subshell
(sim, você precisa do ponto e vírgula)
fonte