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.Réponses:
C'est une limitation de la façon dont le shell rompt les lignes en jetons.
Le shell lit les lignes du fichier d'entrée et selon la section 2 "Introduction au shell", il les convertit soit en un mot, soit en un opérateur :
{est un mot réservé
Certains mots sont des mots réservés
Les mots, pour être reconnus comme des mots, doivent être délimités .
Surtout par des blancs (point 7) et par des opérateurs.
(est un opérateur
Les opérateurs sont autonomes :
Où les "opérateurs" sont soit :
Les opérateurs de redirection sont :
Les opérateurs de contrôle sont :
Conclusion
Ainsi, '(' et ')' sont des opérateurs de contrôle tandis que '{' '}' sont des mots réservés.
Et la même description exacte de votre question se trouve dans la spécification :
Ce qui explique exactement pourquoi un espace (ou un autre délimiteur) est nécessaire après a
{
.Ceci est valable:
Comme ceci:
Cette:
Ou même ceci:
la source
La différence entre les accolades et les parenthèses sont que les accolades (et
!
) sont des mots réservés, tout commefor
,if
,then
etc. , tandis que les parenthèses sont les opérateurs de contrôle. Les mots doivent être séparés par des espaces.Cela signifie que tout comme vous ne pouvez pas avoir
tu ne peux pas avoir
ou
Les espaces affichés dans la grammaire POSIX ne sont pas des espaces qui doivent être présents dans les données d'entrée du shell, mais simplement un moyen d'afficher la grammaire elle-même. C'est le fait que les accolades sont des mots réservés qui implique qu'ils doivent être entourés d'espaces, contrairement aux parenthèses d'un sous-shell.
la source
(
comme opérateur? Ce n'est pas dans la section de grammaire au moins;
. Merci pour ça.()
comme des opérateurs de contrôle comme|
dans le cas où les deux impliquent des sous-coquilles. Et{ }
fonctionne dans le shell actuel et ne peut pas impliquer de sous-shell.(
opérateur