Une raison simplifiée est l'existence d'un caractère: space.
Les développements d'accolades ne traitent pas les espaces (non cités).
Une {...}
liste a besoin d'espaces (non cités).
La réponse plus détaillée est la façon dont le shell analyse une ligne de commande .
La première étape pour analyser (comprendre) une ligne de commande consiste à la diviser en plusieurs parties.
Ces parties (généralement appelées mots ou jetons) résultent de la division d'une ligne de commande à chaque méta-caractère du lien :
- Divise la commande en jetons séparés par le jeu fixe de méta-caractères: ESPACE, TAB, NEWLINE,;, (,), <,>, | et &. Les types de jetons incluent des mots, des mots-clés, des redirecteurs d'E / S et des points-virgules.
Méta-personnages: spacetabenter;,<>|et &.
Après division, les mots peuvent être d'un type (tel que compris par la coque):
- Commandes préalables:
LC=ALL ...
- Commander
LC=ALL echo
- Arguments
LC=ALL echo "hello"
- La redirection
LC=ALL echo "hello" >&2
Expansion de Brace
Si une "chaîne d'accolade" (sans espaces ni méta-caractères) est un mot unique (comme décrit ci-dessus) et qu'elle n'est pas entre guillemets , elle est candidate pour le "développement d' accolade ". Plus de contrôles sont effectués sur la structure interne plus tard.
Ainsi, ceci: est {ls,-l}
qualifié d '"extension de support" pour devenir ls -l
, en tant que first word
ou argument
(dans bash, zsh est différent).
$ {ls,-l} ### executes `ls -l`
$ echo {ls,-l} ### prints `ls -l`
Mais ce ne sera pas: {ls ,-l}
. Bash se divisera spaceet analysera la ligne en deux mots: {ls
et ,-l}
qui déclenchera un command not found
(l'argument ,-l}
est perdu):
$ {ls ,-l}
bash: {ls: command not found
Votre ligne: {ls;echo hi}
ne deviendra pas une "extension Brace" à cause des deux méta-caractères ;et space.
Il sera divisé en ces trois parties: {ls
nouvelle commande: echo
hi}
. Comprenez que cela ;déclenche le démarrage d'une nouvelle commande. La commande {ls
ne sera pas trouvée et la prochaine commande sera imprimée hi}
:
$ {ls;echo hi}
bash: {ls: command not found
hi}
S'il est placé après une autre commande, il lancera quand même une nouvelle commande après le ;:
$ echo {ls;echo hi}
{ls
hi}
liste
L' une des « commandes composé » est une « liste Brace » (mes mots): { list; }
.
Comme vous pouvez le constater, il est défini avec des espaces et une fermeture ;
.
Les espaces et ;sont nécessaires parce que les deux {
et }
sont « réservées mots ».
Et par conséquent, pour être reconnu comme un mot, il doit être entouré de méta-caractères (presque toujours:) space.
Comme décrit au point 2 de la page liée
- Vérifie le premier jeton de chaque commande pour voir s'il s'agit de ...., {, ou (, alors la commande est en fait une commande composée.
Votre exemple: {ls;echo hi}
n'est pas une liste.
Il faut une fermeture ;et un espace (au moins) après {. Le dernier }est défini par la fermeture ;.
Ceci est une liste { ls;echo hi; }
. Et ceci { ls;echo hi;}
est également (moins couramment utilisé, mais valide) (Merci @choroba pour l'aide).
$ { ls;echo hi; }
A-list-of-files
hi
Mais comme argument (le shell connaît la différence) à une commande, il déclenche une erreur:
$ echo { ls;echo hi; }
bash: syntax error near unexpected token `}'
Mais faites attention à ce que vous pensez que la coque analyse:
$ echo { ls;echo hi;
{ ls
hi
{
interprété comme une liste de commandes s'il apparaît au début d'une commande et comme un développement d'accolade sinon, mais je ne suis pas sûr.