O shell tem permissão para otimizar comandos de término inúteis?

26

Se um shell for solicitado a executar um comando provavelmente inútil ( ou parcialmente inútil ) conhecido por terminar, como cat hugeregularfile.txt > /dev/null , ele poderá ignorar a execução desse comando ( ou executar um comando mais barato equivalente, digamos, touch -a hugeregularfile.txt )?

Mais geralmente, é o shell semelhante aos compiladores C, pois ele pode executar qualquer transformação no código-fonte, desde que o comportamento externamente observável seja como-se a máquina abstrata avaliou?

EDITAR

Nota: Minha pergunta originalmente feita tinha um título que perguntava se o shell é permitido fazer essas otimizações, não se deveria ou mesmo se implementações podem fazê-las. Estou mais interessado na teoria do que na prática, embora ambos sejam bem-vindos.

    
por Iwillnotexist Idonotexist 10.03.2014 / 06:38

4 respostas

26

Não, isso seria uma má ideia.

cat hugeregularfile.txt > /dev/null e touch -a hugeregularfile.txt não são iguais. cat lerá o arquivo inteiro, mesmo se você redirecionar a saída para /dev/null . E ler o arquivo inteiro pode ser exatamente o que você quer. Por exemplo, para armazená-lo em cache, para que as leituras posteriores sejam significativamente mais rápidas. A concha não pode conhecer sua intenção.

Da mesma forma, um compilador C nunca irá otimizar a leitura de um arquivo, mesmo se você não olhar para as coisas que você lê.

    
por 10.03.2014 / 09:01
20

Não, pois /dev/null é apenas um nome, que pode ser usado para qualquer outro dispositivo ou para um arquivo diferente do que "normalmente" é um coletor de dados.

Portanto, um shell (ou qualquer outro programa) não tem idéia, com base no nome, se o arquivo está gravando está fazendo algo "real" com os dados. Não há também AFAIK chamadas de sistema que o programa de shell pode fazer, para determinar que, e. o descritor de arquivos não está realmente fazendo nada.

Sua comparação com a otimização do código ausente em um programa C não funciona, já que um shell não possui a visão geral total que um compilador C possui sobre um pedaço de código-fonte. Um shell não sabe o suficiente sobre /dev/null para otimizar seu exemplo, mais como um compilador C não sabe o suficiente sobre o código em uma chamada de função que ele vincula dinamicamente, para não fazer a chamada.

    
por 10.03.2014 / 07:09
14

Ele não otimizará os comandos em execução (e você já recebeu uma série de ótimas respostas dizendo por que não deveria), mas pode otimizar os garfos, tubos / tomadas, leituras em alguns casos. O tipo de otimizações que pode fazer:

  • Com a maioria dos shells modernos, o último comando em um script geralmente será executado no processo do shell, a menos que alguns trap s tenham sido definidos. Por exemplo, em sh -c ls , a maioria das implementações sh ( bash , mksh , ksh , zsh , yash , algumas versões de ash ) não irão bifurcar um processo para executar ls .
  • em ksh93 , a substituição de comando não criará um processo de pipe ou fork até que um comando externo seja chamado ( $(echo foo) , por exemplo, será expandido para foo sem um pipe / socketpair ou fork).
  • o read interno de alguns shells ( bash , AT & T ksh ) não fará leituras de byte único se detectar stdin for procurado (nesse caso eles farão leituras grandes e buscarão de volta até o final do que eles devem ler).
por 10.03.2014 / 10:54
7

Ao ver cat hugeregularfile.txt > /dev/null , o shell não pode acreditar que a ação é inútil - cat não faz parte da casca e poderia fazer qualquer coisa na teoria, e também na prática.

Por exemplo, o usuário pode ter renomeado o executável rm para cat e, de repente, a linha executa um comportamento externamente observável, ou seja, removendo o arquivo.

O usuário pode ter compilado uma versão do cat que entra em um loop infinito, portanto, o shell não pode assumir que é "conhecido por encerrar" como você sugere.

Alguém pode ter instalado uma versão do cat que funciona como pretendido, mas com um efeito colateral extra de instalar um rootkit se ele já tiver sido executado com privilégios adequados - novamente, o shell deve executá-lo devidamente.

    
por 10.03.2014 / 17:01