TL; DR : Por que o grupo de chaves POSIX precisa de espaços após a {
palavra reservada, mas o subshell não após a palavra reservada (
?
A gramática de shell POSIX define o grupo de chaves e o subshell da seguinte maneira
brace_group : Lbrace compound_list Rbrace
subshell : '(' compound_list ')'
Agora, se estamos lendo isso literalmente, os espaços são significativos. Isso significa que deve haver espaço delineando a chave de abertura e fechamento e o parêntese, como
{ echo hello world; }
( echo hello world )
Isso também se alinharia às definições de comando composto :
Cada um desses comandos compostos possui uma palavra reservada ou operador de controle no início e uma palavra ou operador reservado terminador correspondente no final.
No entanto, o que não faz sentido é o porquê (list)
e ( list )
funciona muito bem (esse espaço depois (
não é necessário), no entanto, a expansão da cinta precisa ter um espaço à frente, ou seja {echo hello;}
, não funcionaria.
É claro que a palavra reservada sendo tratada como palavra shell faria sentido precisar de um espaço depois para se alinhar com o conceito de divisão de campos , no entanto, a própria definição não faz menção de espaços. Além disso, se {
e (
são consideradas palavras reservadas pela definição POSIX de comando composto, por que são tratadas de maneira diferente em relação ao caractere de espaço após essas palavras reservadas? Agora, o manual do ksh (1) declara:
As palavras, que são seqüências de caracteres, são delimitadas por caracteres de espaço em branco sem aspas (espaço, tabulação e nova linha) ou metacaracteres (<,>, |,;, &, (e))
Em outras palavras, faz sentido que o ksh reconheça (
como delimitador de palavras, onde a primeira palavra seria um comando ou atribuição de variável. POSIX, no entanto, não parece ser mencionado (
como meta-caractere. A única explicação possível que encontrei no que diz respeito à gramática POSIX é que ela {
é considerada um "token", onde (
não está listado como um.
/* These are reserved words, not operator tokens, and are
recognized when reserved words are recognized. */
%token Lbrace Rbrace Bang
/* '{' '}' '!' */
Então, qual seria o raciocínio preciso para essa discrepância?
Notas de respostas aceitas:
Movi a marca de seleção aceita para a resposta de Isaac, pois fornece ao formulário o padrão em si que aborda diretamente minha pergunta:
Por exemplo, '(' e ')' são operadores de controle, de modo que não
<space>
é necessário em (lista). No entanto, '{' e '}' são palavras reservadas em {list;}, portanto, neste caso, as iniciais<space>
e<semicolon>
são obrigatórias.Aceitando a resposta de Kusalananda. A resposta de Kusalananda aborda o que eu precisava, embora principalmente do ponto de vista informal e intuitivo; indica que{
é uma palavra reservada e(
é operador. Michael Homer também observou o mesmo nos comentários - que a definição do Comando Composto afirma (ênfase adicionada):Cada um desses comandos compostos possui uma palavra reservada ou operador de controle no início
{
são definidos como palavras reservadas, semelhantesfor
ouwhile
listadas na Shell Grammar (consulte o último bloco de código na pergunta)A Seção 2.9 declara (grifo nosso):
Em particular, as representações incluem espaçamento entre tokens em alguns lugares onde
<blank>
s não seria necessário (quando um dos tokens é um operador).Enquanto o padrão não define explicitamente
(
como operador,(
é referido como operador; especificamente, a seção 2.9.2 dizSe o pipeline começar com a palavra reservada! e command1 é um comando subshell, o aplicativo deve garantir que o operador (no início do comando1 seja separado do! por um ou mais caracteres. O comportamento da palavra reservada! imediatamente seguido pelo operador (não é especificado.
Pergunta sobre Stack Overflow by Digital Trauma indica a Seção 2.4 em Palavras reservadas:
Este reconhecimento deve ocorrer apenas quando nenhum dos caracteres é citado e quando a palavra é usada como:
-A primeira palavra de um comando
Como mencionado na resposta de Kusalananda "Os espaços mostrados na gramática POSIX não são espaços que precisam estar nos dados de entrada do shell, mas apenas uma maneira de exibir a gramática em si. É o fato de que os aparelhos são palavras reservadas que implica que eles precisam ser cercados por espaços em branco "Como mencionado por Michael Homer nos comentários:" Se os espaços fossem significativos por si mesmos, eles precisariam ser listados na produção "
Caso encerrado.
{
e (
são considerados palavras reservadas pela definição POSIX de comando composto", cf. "Cada um desses comandos compostos possui uma palavra reservada ou operador de controle no início".
' '
). Em vez disso, os espaços estão implícitos em quais símbolos são palavras.
command : simple_command | compound_command | compound_command redirect_list | function_definition ;
é uma produção que diz onde você pode ter um comando, pode ser um comando simples, comando composto ou comando composto com redirecionamento ou definição de função.