Question Pourquoi les espaces sont-ils parfois nécessaires autour des métacaractères?


Il y a quelques mois, j'ai tatoué un fourchette bombe sur mon bras, et j'ai sauté les espaces, parce que je pense que c'est plus joli sans eux. Mais à ma grande consternation, parfois (pas toujours) quand je l'exécute dans un shell il ne démarre pas une bombe de fourchette, mais il donne juste une erreur de syntaxe.

bash: syntax error near unexpected token `{:'

Hier c'est arrivé quand j'ai essayé de le faire tourner chez un ami Frapper shell, puis j'ai ajouté l'espace et il a soudainement travaillé, :(){ :|:& };: au lieu de :(){:|:&};:

Est-ce que les espaces comptent? ai-je tatoué une erreur de syntaxe sur mon bras ?!

Il semble toujours fonctionner dans zsh, mais pas dans Bash.

Une question connexe n'explique rien sur les espaces, ce qui est vraiment ma question; Pourquoi les espaces sont-ils nécessaires pour que Bash puisse l'analyser correctement?


533
2018-01-17 13:03


origine


Réponses:


Il y a une liste de caractères qui séparent les jetons dans BASH. Ces personnages sont appelés métacaractères et ils sont |, &, ;, (, ), <, >, espace et languette. D'autre part, des accolades ({ et }) sont juste des caractères ordinaires qui composent des mots.

Omettre le deuxième espace avant } fera, depuis & est un métacaractère. Par conséquent, votre tatouage devrait avoir au moins un caractère d'espace.

:(){ :|:&};:

262
2018-01-17 13:20



Juste tatouer un

#!/bin/zsh

shebang dessus et tout ira bien.


76
2018-01-29 12:26



Les accolades ressemblent plus à des mots-clés impairs qu'à des symboles spéciaux et nécessitent des espaces. Ceci est différent des parenthèses, par exemple. Comparer:

(ls)

qui fonctionne, et:

{ls}

qui cherche une commande nommée {ls}. Pour travailler, ça doit être:

{ ls; }

Le point-virgule arrête l'accolade fermante en tant que paramètre pour ls.

Tout ce que vous avez à faire est de dire aux gens que vous utilisez une police proportionnelle avec un caractère d'espace plutôt étroit.


49
2018-01-17 13:09



Bien qu'il ne soit pas facilement visible dans la police tatoo, il existe en réalité une marque d'ordre d'octet (BOM) entre l'accolade et le côlon (vous avez peut-être été suffisamment intoxiqué quand vous avez reçu le tatoo, mais il est vraiment là) . Cela laisse trois possibilités évidentes:

  1. Vous n'avez pas réussi à taper la nomenclature lorsque vous avez transcrit le code. Le résultat est une application évidente de GIGO. Le shell ne reconnaît tout simplement pas une nomenclature qui n'est pas présente dans votre transcription échouée.
  2. Votre coquille est trop vieille. Il ne reconnaît pas les caractères Unicode, de sorte que la nomenclature (et probablement tous les autres caractères Unicode) est complètement ignorée, même si une nomenclature, sauf le début d'un fichier, est censée être traitée comme un espace sans rupture et de largeur nulle .
  3. Votre coquille est trop nouvelle. L'utilisation d'une nomenclature en tant que ZWNBS est obsolète et les auteurs ont implémenté une version future d'Unicode dans laquelle cette utilisation n'est plus autorisée.

40
2018-01-22 03:58



et puis j'ai ajouté l'espace et ça a soudainement fonctionné ...

C'est à cause de la façon dont le shell analyse. Vous avez besoin d'un espace après le début de la définition de la fonction, c'est-à-dire après le {.

foo() { echo hey& }
foo() { echo hey&}
foo(){ echo hey&}

sont valides. D'autre part,

foo() {echo hey&}

n'est pas.


Vous avez réellement besoin d'un tatouage comme celui-ci:

enter image description here


Du la source:

  /* We ignore an open brace surrounded by whitespace, and also
     an open brace followed immediately by a close brace preceded
     by whitespace.  */

Omettre un espace après le { provoque la {echo être interprété comme un seul jeton.


Une forme équivalente de

:(){ :|:& };:

serait

:(){
:|:& };:

Notez qu'il n'y a pas d'espace après { dans la version alternative, mais un saut de ligne provoque le shell à reconnaître { en tant que jeton.


39
2018-01-17 13:12