Estou executando um find
comando cronometrado como usuário normal.
O que eu sei é que o redirecionamento serve para evitar mensagens stdout/stderr no terminal. Se for esse o caso, por que diferentes métodos de redirecionamento levam tempos diferentes? Está de alguma forma relacionado à velocidade de gravação no tty ou há algum outro motivo por trás disso? Alguém poderia me indicar a direção certa para entender isso?
$ id
uid=1000(user1) gid=1000(user1) groups=1000(user1),1001(user2)
$time find /
<truncated output>
real 0m13.902s
user 0m0.197s
sys 0m0.448s
$ time find / >/dev/null
<truncated output>
real 0m0.298s
user 0m0.068s
sys 0m0.206s
$time find / 2> /dev/null
<truncated output>
real 0m13.279s
user 0m0.181s
sys 0m0.405s
$ time find / > /dev/null 2>&1
real 0m0.306s
user 0m0.109s
sys 0m0.174s
Responder1
Quando o seu processo ( find
) precisa realmente escrever a saída, isso obviamente leva muito mais tempo do que quando você diz para descartar a saída.
Quando você usa
find /
, tanto o stdout quanto o stderr são enviados para o seu terminal, e ele precisa escrever ambos (ou seja, os resultados reais e todos os erros de permissão e outros enfeites)Ao usá-lo,
time find / >/dev/null
você elimina a saída padrão do comando, mas ainda imprime todos os erros (se houver). A julgar pelos seus resultados, você tem muitos resultados legítimos e poucos erros.Quando você usa
time find / 2> /dev/null
, a saída padrão do comando ainda está sendo enviada para o seu terminal, mas agora você está simplesmente descartando o stderr. Se você estivesse encontrando um sistema de arquivos que não tinha permissão para ler, isso seria muito rápido.Ao usar
time find / > /dev/null 2>&1
, você está descartando a saída padrão e, em seguida, enviando o erro padrão para onde a saída padrão está sendo enviada,... ou seja, você está descartando ambos. Isso não produzirá nada e, portanto, será o mais rápido de todos os comandos.
Responder2
O que eu sei é que o redirecionamento serve para evitar mensagens stdout/stderr no terminal.
Bem, não: você também pode redirecionar para um arquivo:
find / > ~/all-the-files
Está de alguma forma relacionado à velocidade de gravação no tty?
Em uma palavra, sim.
Independentemente do tipo de terminal que você está usando (console virtual no Linux, um xterm local, algo através de uma conexão SSH), o emulador de terminal real tem que desenhar tudo impresso no terminal, mesmo que neste caso ele vá rolar sair em breve. (Uma conexão encerrada mosh
pode ser uma exceção aqui.)
Em uma conexão de rede, há também o atraso na transferência a ser considerado; alguns dados podem ser armazenados em buffer, se houver muitos, não todos. Se você redirecionar algo para /dev/null
, ele não será salvo em lugar nenhum e também não será desenhado. O redirecionamento para um arquivo também será rápido com quantidades moderadas de dados, já que o sistema operacional provavelmente armazena em cache as gravações na memória e só grava no disco preguiçosamente depois. Com uma grande quantidade de dados, a gravação em disco também pode se tornar um gargalo. (ou, se você conseguiu que o processo escrevesse a saída no modo de E/S síncrona)
Para programas que geram muita saída, apenas o processo de formatar a saída ( printf()
dentro do processo) e chamar o sistema operacional para escrevê-la levaria tempo, mesmo que os dados fossem redirecionados para /dev/null
. Em um caso como esse, poderia ser ainda mais rápido se você conseguisse persuadir o programa a inibir completamente a saída. Este provavelmente não é o caso find
, presumo que seria a velocidade de E/S ou a sobrecarga da chamada do sistema.
Observe também que se você executar find
na mesma árvore de diretórios repetidamente, a primeira vez provavelmente será mais lenta que as outras, já que a primeira vez pode exigir a leitura do disco, enquanto depois disso, muitos dos dados serão armazenados em cache pelo sistema operacional .