Verwendung von ^ als Shell-Metazeichen


19

Ich habe heute ein kleines Drehbuch geschrieben, das Folgendes enthielt

grep -q ^local0 /etc/syslog.conf

Bei der Überprüfung schlug ein Mitarbeiter , dass ^local0da zitiert werden ^Mittel „Rohr“ in der Bourne - Shell. Überrascht von dieser Behauptung habe ich versucht, einen Hinweis darauf zu finden. Nichts, was ich im Internet gefunden habe, deutete darauf hin, dass dies ein Problem war.

Es stellt sich jedoch heraus, dass die Implementierung von bsh(die behauptet, die Bourne-Shell zu sein) unter AIX 7 tatsächlich das folgende Verhalten aufweist:

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

Keine der anderen "Bourne-Shell" -Implementierungen, die ich ausprobiert habe, verhält sich so (das heißt, es ^wird überhaupt nicht als Shell-Metazeichen angesehen). Ich habe shCentOS (was wirklich bash ist) und shFreeBSD (was nicht bash ist) ausprobiert . Ich habe nicht viele andere Systeme zum Ausprobieren.

Wird dieses Verhalten erwartet? Welche Muscheln gelten ^als Pipe-Metazeichen?


1
Ich weiß, dass dies ^ein Negationscharakter in zsh und auch im Regex-Raum ist. Als separater Kommentar wird im Allgemeinen empfohlen, einfache Anführungszeichen in grep-Ausdrücken zu verwenden, um die Portabilität über Shells hinweg zu gewährleisten.
MKC

Die Bourne-Shell hatte eine Menge seltsamer Verhaltensweisen, für die wir in modernem Shell-Code immer noch Umgehungen sehen, z [ x"$foo" = x"bar" ].
Jordanien

bshes ist nicht die Bourne Shell. Der Name wird nur für die Bourne-Shell unter AIX missbraucht. bshist eher eine Shell, die ich 1984 bei der H.Berhold AG unter UNOS (dem ersten UNIX-Klon) eingeführt habe. Beachten Sie, dass AIX 1984 nicht existierte.
schily

Antworten:


21

Die ^Figur als Synonym |stammt aus der Thompson-Schale . Sie wurden zur gleichen Zeit in Unix v4 eingeführt und werden zusammen in der Manpage erwähnt . Sven Mascheck erwähnt, dass dies ^"wahrscheinlich aus praktischen Gründen für frühe Terminals nur in Großbuchstaben eingeführt" wurde, bei denen das Tippen |"etwas mühsam" war .

Die Thompson-Shell ist schon lange nicht mehr vorhanden, aber ihr Nachfolger, die Bourne-Shell, behielt dieselbe Syntax bei (obwohl in der Manpage nur erwähnt wird |).

Nachfolgemuscheln wie ash, bash und ksh verstehen sich nur |als Pipe-Charakter. Auf Open-Source-Unix-Varianten wird es keine echte Bourne-Shell geben, da es lange Zeit keine Open-Source-Version der Bourne-Shell gab. (Ich denke, OpenSolaris enthielt eines, aber es wurde nicht an anderer Stelle übernommen, da es zu diesem Zeitpunkt durch neuere Implementierungen lange veraltet war.)

In der Single-Unix-Spezifikation wird kein ^Sonderzeichen erwähnt, was effektiv bedeutet, dass POSIX-Shells es wörtlich interpretieren sollten¹. Ich glaube nicht, dass es jemals eine POSIX-kompatible Variante der Bourne-Shell gegeben hat (nur unabhängige Implementierungen).

^ist etwas Besonderes in zsh, wenn die Option extendedglobaktiviert ist, aber nicht im sh-Kompatibilitätsmodus. Im Standardmodus weicht es in vielerlei Hinsicht von POSIX ab.

Ich empfehle ^aus Gründen der Klarheit, in einem regulären Ausdruck zu zitieren . Zitieren Sie den regulären Ausdruck in einem Skript, unabhängig davon, welche Zeichen darin enthalten sind.

¹ Mit Ausnahme des ersten Zeichens eines Klammerausdrucks in einem Platzhaltermuster, wobei !es sich um das Standardnegationszeichen handelt, Implementierungen jedoch möglicherweise ^auf die gleiche Weise interpretiert werden.


Danke, der ganze TUHS-Thread von 2003 war aufschlussreich.
Greg Hewgill

Der Vollständigkeit halber möchten Sie vielleicht erwähnen, dass dies ^besonders ist, fishwenn es sich um einen Umleitungsoperator handelt, rc/ eswenn es sich um einen Verkettungsoperator handelt , oder um csh / tcsh / bash / zsh für die Verlaufserweiterung, wenn es sich um das erste Zeichen der Befehlszeile handelt.
Stéphane Chazelas


3

Ja, OpenSolaris enthält die Bourne Shell-Quelle, diese Quelle ist jedoch nicht portierbar.

Eine gepflegte und hoch portable Version der Bourne Shell-Quelle finden Sie hier im schily-*.tar.bz2Archiv.

Hier ist der zugehörige Teil der Quelle in cmd.c:

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

Sie sehen, dies hängt nicht mit einer bestimmten Shell (z. B. der Thompson-Shell) zusammen, sondern mit der Tatsache, dass es in den 1970er Jahren immer noch nur Terminals in Großbuchstaben gab.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.