Espaces à côté des tuyaux

17

J'ai vu history | grep blahet history |grep blah; et history|grep blahfonctionne également, bien que personne ne semble jamais l'utiliser.

Y a-t-il une signification dans les espaces (par exemple, la tuyauterie vers / depuis différentes commandes nécessite une utilisation différente des espaces), ou est-ce toujours arbitraire?

EmmaV
la source
13
Lisibilité, surtout.
jasonwryan du
1
|le tube ou le ;point-virgule sont utilisés par la plupart des shell (bash, ksh, tcsh) comme séparateur de commandes. lorsqu'ils ne sont pas inclus entre guillemets, les espaces blancs avant et après ne sont pas pertinents.
Archemar

Réponses:

24

bashdéfinit plusieurs métacaractères . De man bash:

métacaractère
Caractère qui, lorsqu'il n'est pas cité, sépare les mots. L'un des éléments suivants:
| &; () <> onglet espace

Étant donné que les métacaractères séparent les mots, peu importe qu'ils soient entourés d'espaces. Le symbole de la pipe,, |est un métacaractère et donc, comme vous l'avez remarqué, il n'a pas besoin d'espaces autour de lui.

Notez que [, ], {, }et =sont pas métacaractères. Leur signification, en revanche, dépend fortement de leur entourage par des blancs.

Exemples de situations où des espaces sont et ne sont pas nécessaires

Comme vous l'avez remarqué, peu importe qu'il |soit entouré d'espaces. Prenons quelques exemples qui confondent souvent les utilisateurs bash. Considérer:

$ (date)
Sun Mar  1 12:47:07 PST 2015

Les parens ci-dessus forcent l' dateexécution de la commande dans un sous-shell. Parce que (et )sont des métacaractères, aucun espace n'est nécessaire. Par contre:

$ {date}
bash: {date}: command not found

Puisque {et ne} sont pas des métacaractères, le shell est traité {date}comme un seul mot. Au lieu de rechercher la datecommande, il recherche une commande nommée {date}. Parce qu'il n'en trouve pas, une erreur se produit.

Un autre problème courant est la testcommande. Les éléments suivants fonctionnent avec succès:

$ [ abc ] && echo Yes
Yes

Supprimez les espaces et une erreur se produit:

$ [abc] && echo Yes
bash: [abc]: command not found

Parce que [et ne] sont pas des métacaractères, le shell est traité [.bashrc]comme un seul mot et le résultat, comme dans l' dateexemple, est une erreur.

Les instructions d'affectation sont également sensibles aux espaces. L'affectation suivante a réussi:

$ v=date
$ echo $v
date

Ajoutez un espace et l'affectation échoue:

$ v= date
Sun Mar  1 12:55:05 PST 2015

Dans ce qui précède, le shell est temporairement défini vsur vide, puis exécute la datecommande.

Ajouter un espace avant =provoque également un échec, mais pour une raison différente:

$ v =date
bash: v: command not found

Ici, le shell tente d'exécuter la commande vavec l'argument =date. L'erreur est due au fait qu'il n'a trouvé aucune commande nommée v.

John1024
la source
1
J'ai récemment été victime de la déclaration de mission. J'avais des espaces avant et après le =. Il a fallu un certain temps pour déboguer.
2015
3

Les tuyaux vous permettent d'utiliser la sortie d'un programme comme entrée d'un autre ...

En ce qui concerne les espaces, sa juste question de lisibilité / préférence du personnel comme @jasonwryan l'a mentionné.

Une barre d'espace avant et après "|" est la norme ....

Vous pouvez également l'utiliser avec la colonne -t, non seulement pour rendre votre doublure propre, mais aussi pour votre sortie.

lnydex99uhc:depot_r user$ lsof | grep my | column -t
Microsoft  290  user  txt  REG  1,4  9515016  170972    /Library/Fonts/PCmyoungjo.ttf
bash       359  user  cwd  DIR  1,4  714      12246074  /Users/zatef/hw2/base/active/myapp
zee
la source
2

Il y a un cas où il peut être utile de ne pas utiliser d'espaces. Si vous n'utilisez pas une disposition américano-américaine, vous devrez peut-être utiliser certaines combinaisons comme AltShiftLpour entrer un tuyau. Bien que ce ne soit pas un problème en soi, une conséquence est que parfois vous entrez également des caractères non imprimables avant ou après ce caractère. Par exemple, sur un clavier Macbook Pro français, je dois utiliser AltShiftLpour saisir |. Lorsque vous tapez rapidement, vous pouvez accidentellement taper ceci: AltShift( L, Space)

$ sudo dmesg | tail
zsh: command not found:  tail

echo "sudo dmesg | tail" | od -a
0000000    s   u   d   o  sp   d   m   e   s   g  sp   |         t   a
0000020    i   l  nl

Si vous n'êtes pas au courant de la AltShiftSpacesaisie d'un espace différent (l'espace insécable ( U + 00A0 )), l'erreur suivante peut être difficile à comprendre:zsh: command not found:  tail

alecail
la source
1

La seule signification des espaces dans ce cas est l'esthétique.
Ou en d'autres termes, utile pour rendre les commandes plus lisibles pour un humain.

asoundmove
la source