Os programas 'if' e 'then' são realmente

15

Eu li que o ponto-e-vírgula é usado para separar programas:

$ echo 3; ls -la

Isso significa que if , then e else são programas separados aqui?

$ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi

Esta questão não é sobre ponto e vírgula.

    
por Max Koretskyi aka Wizard 20.01.2017 / 19:43

5 respostas

26

O ; separa as instruções (falando frouxamente). É (quase) sempre possível substituir um ; por uma nova linha.

Dizer que ; separa dois programas, portanto, if e then devem ser "programas" é um pouco simplista, pois uma declaração pode ser feita de palavras reservadas, funções de shell, utilitários internos e externos utilitários, e combinações destes usando pipes e operadores booleanos etc. etc.

Tanto if como then são palavras reservadas na gramática da shell não "programas". Aqui eles são usados para construir o que é tecnicamente chamado de comando composto .

echo é provavelmente um utilitário interno no shell (mas não precisa ser), e ls é provavelmente um utilitário externo (ou "programa" como você diz).

    
por 20.01.2017 / 20:14
7
Embora seja uma primeira aproximação justa quando se está começando a aprender os fundamentos básicos do uso de shells, no nível de "aqui está como um programa é executado" e "aqui está como um executa vários programas um após o outro em um linha única ", não é verdade.

O mais difícil de entender para um iniciante, mas a explicação mais correta é que a linguagem shell é uma linguagem de computador . Tem uma sintaxe . Essa sintaxe compreende vários elementos lexicais incluindo (entre outras coisas) novas linhas, operadores, palavras e palavras reservadas.

if , then , else e fi são todas palavras reservadas . Eles têm significados particulares quando analisa a entrada que se dá a um shell, de acordo com sua gramática . Da mesma forma, ; é um separador operador .

A entrada na linguagem shell é, portanto, tomada como um todo, um programa de computador que é interpretado por outro programa, um interpretador , o shell. Suas partes gramaticais individuais não são programas. A linguagem shell é uma maneira de especificar (outros) programas para o shell rodar.

[ não é um elemento léxico especial na gramática da shell, como um operador. É uma palavra comum, que nomeia um desses programas chamado [ . Muitos shells têm uma versão integrada deste programa, combinada no código do próprio programa shell, mas você também pode encontrar um programa externo por esse nome em algum lugar, como /bin/[ ou /usr/bin/[ , que os programas diferentes de podem invocar. Igualmente, ] também não é um elemento léxico de shell especial. É uma palavra comum, que se torna um argumento para o programa [ . O programa [ requer que seu argumento final, quando executado, seja ] , o qual ele então ignora.

Outro programa semelhante chamado em sua pergunta é echo . Novamente, a maioria dos shells possui uma versão interna deste programa. Mas, novamente, há também uma versão externa do programa, em algum lugar, como /bin/echo ou /usr/bin/echo , para os programas diferentes de invocar.

Um terceiro programa chamado em sua pergunta é ls . Shells geralmente não possuem versões internas deste programa, e é um programa externo, encontrado em algum lugar como /bin/ls ou /usr/bin/ls .

Para o shell Bourne Again, você pode ler mais sobre isso em Recursos Básicos do Shell da documentação de informações do shell GNU Bourne Again. Outras conchas têm gramáticas diferentes, naturalmente. A Especificação Unix Única descreve uma sintaxe que todas as shells em conformidade com POSIX (em seus modos em conformidade com POSIX) devem aderir.

Leitura adicional

  • " Gramática de concha ". Linguagem de comando do shell . Especificações Básicas Problema 7. O Grupo Aberto. IEEE 1003.1-2008. ISBN 1937218812.
  • test . Utilitários . Especificações Básicas Problema 7. O Grupo Aberto. IEEE 1003.1-2008. ISBN 1937218812.
  • " Gramática de concha ". O Manual do Z Shell . versão 5.3.1. 2017.
por 20.01.2017 / 20:49
5

Na verdade, não é exagero pensar em if , then e else como programas externos. Na verdade, o shell Thompson na primeira edição original do Unix implementou if e goto como programas externos. Isso é possível porque o subprocesso compartilha descritores de arquivo com o processo de shell, portanto, um goto (direto) só precisa ler a entrada até encontrar o rótulo de destino e sair. Veja concha de Thompson .

    
por 20.01.2017 / 21:03
2

Os then e else não são programas. As outras partes são. Observe que não há ; 'diretamente depois deles, mas depois do comando eles precedem.

O [ ... ] é um comando e precisa do ; , se seguido pelo início de outro comando.

AFAIK, todas as estruturas de controle no Bash, e provavelmente a maioria das * nix shells, são as mesmas. São instruções para o intérprete. O teste ou condição, por outro lado, usa um programa / processo que é "executado" e é um comando. Como then faz parte da linha que leva ao comando echo , ele precisa ser separado por uma nova linha do comando anterior [ ... ] . Ele não precisa ser separado do comando que ele controla, o echo yes .

Legalmente, embora feio e difícil de ler, você também pode fazer isso.

if [ $VARIABLE == abcdef ]
then echo yes
else echo no
fi

Observe que não há necessidade de ; entre os controles, mesmo que eles não estejam em sua própria linha.

Curiosamente, toda a estrutura de controle ( if ... fi ) é um comando shell, e a totalidade tem que terminar com uma nova linha ou um ; . A última linha não pode ser fi echo done , mas deve ser fi; echo done . O mesmo que uma atribuição VARIABLE='abcdef' é um comando.

Apesar de todas as estruturas de controle serem comandos, elas ainda não são programas.

    
por 20.01.2017 / 20:35
2

if , elif , then e fi são palavras-chave reservadas usadas para implementar uma das construções referidas como um comando composto no shell, o que significa que não pode haver um comando (ou melhor, outro comando) por qualquer um desses nomes no shell. A finalidade do ; em geral não é separar comandos, mas finalizar um comando list . Por exemplo, o seguinte é uma instrução if válida:

if echo foo; echo bar; echo baz; then echo done; echo really done; fi

A condição da instrução if é a lista de comandos echo foo; echo bar; echo baz . O analisador sabe que a condição acabou, porque then , que imediatamente segue um ponto-e-vírgula, não pode ser um comando porque é uma palavra-chave reservada. Assim, sabe que o que segue é o começo do corpo. Da mesma forma, then é uma palavra-chave reservada e, portanto, não pode ser um terceiro comando no corpo da instrução fi , mas marca o final do comando composto.

    
por 22.01.2017 / 05:12