Utilisation de ^ comme métacaractère shell


19

J'ai écrit aujourd'hui un petit script qui contenait

grep -q ^local0 /etc/syslog.conf

Au cours de l'examen, un collègue a suggéré de ^local0le citer parce qu'il ^signifie «pipe» dans le shell Bourne. Surpris par cette affirmation, j'ai essayé de retrouver toute référence qui en faisait mention. Rien de ce que j'ai trouvé sur Internet ne suggérait que c'était un problème.

Cependant, il s'avère que l'implémentation de bsh(qui prétend être le shell Bourne) sur AIX 7 a en fait ce comportement:

> bsh
$ ls ^ wc
      23      23     183
$ ls | wc
      23      23     183

Aucune des autres implémentations de "Bourne shell" que j'ai essayées ne se comporte de cette façon (c'est-à-dire qu'elle ^n'est pas du tout considérée comme un métacaractère de shell). J'ai essayé shsur CentOS (qui est vraiment bash) et shsur FreeBSD (qui n'est pas bash). Je n'ai pas beaucoup d'autres systèmes à essayer.

Ce comportement est-il attendu? Quels coquilles considèrent ^comme un métacaractère de tuyau?


1
Je sais que ^c'est un caractère de négation dans zsh et aussi dans l'espace regex. Comme commentaire séparé, il est généralement conseillé d'utiliser des guillemets simples dans l'expression grep pour la portabilité entre les shells.
mkc

Le shell bourne avait beaucoup de comportements étranges pour lesquels nous voyons toujours des solutions dans le code shell moderne, par exemple [ x"$foo" = x"bar" ].
jordanm

bshce n'est pas le Bourne Shell. Le nom est utilisé abusivement pour le Bourne Shell sur AIX uniquement. bshest plutôt un shell introduit par moi en 1984 chez H.Berhold AG sous UNOS (le premier clone UNIX). Notez qu'AIX n'existait pas en 1984.
schily

Réponses:


21

Le ^personnage comme synonyme de |remonte à la coquille de Thompson . Ils ont été introduits en même temps dans Unix v4 et sont mentionnés ensemble dans la page de manuel . Sven Mascheck mentionne qu'il a ^été «probablement [introduit] pour des raisons de commodité sur les premiers terminaux uniquement en majuscules» où la saisie |était «quelque peu pénible» .

Le shell Thompson est révolu depuis longtemps, mais son successeur le shell Bourne a conservé la même syntaxe (même si sa page de manuel ne mentionne que |).

Les obus successeurs tels que ash, bash et ksh ne comprennent |que le caractère de tuyau. Vous n'allez pas trouver un véritable Bourne shell sur les variantes unix open source car pendant longtemps il n'y a pas eu de version open source du Bourne shell. (Je pense qu'OpenSolaris en a inclus un, mais il n'a pas été adopté ailleurs car à cette époque il était depuis longtemps obsolète par les nouvelles implémentations).

La spécification Single Unix ne mentionne pas ^de caractère spécial, ce qui signifie que les shells POSIX doivent l'interpréter littéralement¹. Je ne pense pas qu'il y ait jamais eu de variante entièrement compatible POSIX du shell Bourne (uniquement des implémentations indépendantes).

^est spécial dans zsh lorsque l'option extendedglobest activée, mais pas dans son mode de compatibilité sh. Dans son mode par défaut, il s'écarte de POSIX de plusieurs façons.

Je recommande de toute façon de citer ^une expression régulière pour plus de clarté. Citez l'expression régulière dans un script, quels que soient les caractères qui y figurent.

¹ Sauf en tant que premier caractère d'une expression entre crochets dans un motif générique, où !est le caractère de négation standard, mais les implémentations peuvent également interpréter ^de la même manière.


Merci, tout ce fil TUHS de 2003 a été instructif.
Greg Hewgill

Pour être complet, vous voudrez peut-être mentionner que ^c'est spécial dans le fishcas où il s'agit d'un opérateur de redirection, rc/ esoù il s'agit d'un opérateur de concaténation , ou csh / tcsh / bash / zsh pour l'expansion de l'historique lorsqu'il s'agit du premier caractère de la ligne de commande.
Stéphane Chazelas


3

Oui, OpenSolaris inclut la source Bourne Shell mais cette source n'est pas portable.

Une version maintenue et hautement portable de la source Bourne Shell peut être trouvée ici dans les schily-*.tar.bz2archives.

Voici la partie connexe de la source dans cmd.c:

/* 
* ^ is a relic from the days of UPPER CASE ONLY tty model 33s 
*/ 
if ((t = item(TRUE)) != 0 && (wdval == '^' || wdval == '|')) 

Vous voyez, cela n'est pas lié à un shell spécifique (par exemple le shell Thompson) mais au fait que dans les années 1970, il n'y avait encore que des terminaux en majuscules.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.