Por que o ponto e vírgula não é aceito depois disso?

6

Sou novo em programação shell e percebi que o seguinte é aceito:

if [ $table = "Session" ]; then
continue; fi

E assim é o seguinte:

if [ $table = "Session" ]; then continue; fi

Enquanto o seguinte produz um erro de sintaxe:

if [ $table = "Session" ]; then; continue; fi

Por que a palavra-chave then é diferente das outras?

    
por Benjamin 25.09.2013 / 00:17

2 respostas

13

Porque then não é um comando nem um shell incorporado, mas na verdade faz parte da sintaxe if . De man bash :

   if list; then list; [ elif list; then list; ] ... [ else list; ] fi
          The  if  list is executed.  If its exit status is zero, the then
          list is executed.  Otherwise, each  elif  list  is  executed  in
          turn,  and  if  its  exit status is zero, the corresponding then
          list is executed and the command completes.  Otherwise, the else
          list  is executed, if present.  The exit status is the exit sta‐
          tus of the last command executed, or zero if no condition tested
          true.

Então isso:

if [ $table = "Session" ]; then continue; fi

funciona porque os comandos [ $table = "Session" ] e continue são comandos independentes; eles compõem a respectiva parte list do comando if . Basta colá-los em um shell interativo e você verá que eles não causarão erros de sintaxe:

martin@martin:~$ export table=test
martin@martin:~$ [ $table = "Session" ]
martin@martin:~$ continue
bash: continue: only meaningful in a 'for', 'while', or 'until' loop

Por outro lado, then não é um comando real que pode ser usado sozinho:

martin@martin:~$ then
bash: syntax error near unexpected token 'then'

Assim, nos dois primeiros exemplos, você está usando if da mesma forma que a página do manual descreve:

if list; then list; fi

Mas se você colocar um ; atrás de then , bash verá isso como um erro de sintaxe. Reconhecidamente, a sintaxe da shell pode parecer um pouco confusa às vezes, especialmente quando você está apenas começando a usá-la. Eu me lembro de estar muito confuso sobre o fato de que requer espaços em torno de [ e ] , mas uma vez que você percebe que [ é na verdade um comando ou shell embutido, é compreensível. :)

    
por 25.09.2013 / 00:39
7

Você precisa colocar um ponto-e-vírgula após um comando. [ … ] é um comando, assim como continue . Por outro lado, if , then e fi não são comandos: são palavras reservadas.

if parece um comando, mas isso é quase sempre seguido por exatamente um comando. É válido escrever

if print_table_value >foo; [ "$(cat foo)" = "Session" ]; then …

que também pode ser apresentado de várias maneiras, como

if
  print_table_value >foo
  [ "$(cat foo)" = "Session" ]
then
…

A sintaxe geral de um comando condicional é

if compound-list then compound-list
(elif compound-list then compound-list)*
(else compound-list then compound-list)?
fi

onde

  • As quebras de linha são apenas para leitura.
  • Uma lista de compostos é uma lista de comandos, cada um terminado por ; ou nova linha.
  • (…) ? indica uma parte opcional e (…) * indica uma parte que pode ser repetida 0, 1 ou muitas vezes.

As palavras-chave só são reconhecidas como tal no início de um comando.

Um comando condicional deve terminar com a palavra-chave fi . Isso não elimina a necessidade de segui-lo por um operador se algum outro comando aparecer após ele; Por exemplo, se a condicional for seguida por outro comando, é necessário que haja um ; ou uma nova linha entre eles; se a condicional for executada em segundo plano, ela precisa ser seguida por & , etc.

    
por 25.09.2013 / 00:52

Tags