TL; DR : Pourquoi le groupe d'accolades POSIX a-t-il besoin d'espaces après le {
mot réservé mais pas le sous-shell après le mot réservé (
?
La grammaire du shell POSIX définit le groupe d'accolades et le sous-shell comme suit
brace_group : Lbrace compound_list Rbrace
subshell : '(' compound_list ')'
Maintenant, si nous lisons cela littéralement, les espaces sont importants. Cela signifierait qu'il doit y avoir un espace délimitant l'accolade d'ouverture et de fermeture et la parenthèse comme dans
{ echo hello world; }
( echo hello world )
Cela s'alignerait également avec les définitions des commandes composées :
Chacune de ces commandes composées a un mot réservé ou un opérateur de commande au début, et un mot ou opérateur réservé de terminaison correspondant à la fin.
Cependant, ce qui n'a pas de sens, c'est pourquoi (list)
et ( list )
fonctionne très bien (cet espace (
n'est pas nécessaire après), mais l'expansion de l'accolade doit avoir un espace de tête, c'est {echo hello;}
-à- dire ne fonctionnerait pas.
Bien sûr, un mot réservé traité comme un mot shell aurait du sens d'avoir besoin d'un espace par la suite pour s'aligner sur le concept de division de champ , mais la définition elle-même ne fait aucune mention d'espaces. De plus, si {
et (
sont tous deux considérés comme des mots réservés par la définition POSIX de la commande composée, pourquoi sont-ils traités différemment en ce qui concerne le caractère espace après ces mots réservés? Maintenant, le manuel de ksh (1) indique:
Les mots, qui sont des séquences de caractères, sont délimités par des espaces blancs sans guillemets (espace, tabulation et nouvelle ligne) ou des méta-caractères (<,>, |,;, &, (et))
En d'autres termes, il est logique que ksh reconnaîtrait (
comme délimiteur de mot, où le premier mot serait une commande ou une affectation de variable. POSIX, cependant, ne semble pas mentionner (
comme méta-caractère. La seule explication possible que j'ai trouvée en ce qui concerne la grammaire POSIX est qu'elle {
est considérée comme un "jeton", où as (
n'est pas répertorié comme un.
/* These are reserved words, not operator tokens, and are
recognized when reserved words are recognized. */
%token Lbrace Rbrace Bang
/* '{' '}' '!' */
Alors, quel serait le raisonnement précis de cet écart?
Notes de réponse acceptées:
Déplacement de la coche acceptée dans la réponse d' Isaac car elle fournit une forme standard de la norme elle - même qui répond directement à ma question:
Par exemple, '(' et ')' sont des opérateurs de contrôle, de sorte qu'aucun
<space>
n'est nécessaire dans (liste). Cependant, '{' et '}' sont des mots réservés dans {list;}, de sorte que dans ce cas, le début<space>
et<semicolon>
sont requis.Accepter la réponse de Kusalananda. La réponse de Kusalananda répond à ce dont j'avais besoin, mais surtout d'un point de vue informel et intuitif; il indique qu'il{
s'agit d'un mot réservé et qu'il(
est opérateur. Michael Homer a également noté la même chose dans les commentaires - selon la définition de la commande composée (italiques ajoutés):Chacune de ces commandes composées a un mot réservé ou un opérateur de contrôle au début
{
sont définis comme des mots réservés, similaires àfor
ouwhile
, répertoriés dans la grammaire du shell (voir le dernier bloc de code de la question)La section 2.9 précise (je souligne):
En particulier, les représentations incluent l'espacement entre les jetons à certains endroits où
<blank>
s ne serait pas nécessaire (lorsque l'un des jetons est un opérateur).Bien que la norme ne définisse pas explicitement
(
comme un opérateur,(
est appelée opérateur; en particulier, la section 2.9.2 ditSi le pipeline commence par le mot réservé! et command1 est une commande de sous-shell, l'application doit s'assurer que l'opérateur (au début de la commande1 est séparé du! par un ou plusieurs caractères. Le comportement du mot réservé! immédiatement suivi par l'opérateur (n'est pas spécifié).
La question sur le débordement de pile par Digital Trauma souligne la section 2.4 sur les mots réservés:
Cette reconnaissance ne se produit que si aucun des caractères n'est cité et lorsque le mot est utilisé comme:
-Le premier mot d'une commande
Comme mentionné dans la réponse de Kusalananda "Les espaces affichés dans la grammaire POSIX ne sont pas des espaces qui doivent être là dans les données d'entrée du shell, mais juste un moyen d'afficher la grammaire elle-même. C'est le fait que les accolades sont des mots réservés qui implique que ils doivent être entourés d'espaces blancs "Comme mentionné par Michael Homer dans les commentaires:" Si les espaces étaient importants en soi, ils devraient être répertoriés dans la production "
Affaire classée.
{
et (
sont tous deux considérés comme des mots réservés par la définition POSIX de la commande composée" cf. "Chacune de ces commandes composées a un mot réservé ou un opérateur de contrôle au début".
' '
). Au lieu de cela, les espaces sont impliqués par ce que les jetons sont des mots.
command : simple_command | compound_command | compound_command redirect_list | function_definition ;
va de même pour une production qui indique où vous pouvez avoir une commande, il peut s'agir d'une commande simple, d'une commande composée ou d'une commande composée avec redirection ou d'une définition de fonction.