Uso de ^ como metacarácter de shell

19

Hoy escribí un pequeño guión que contenía

grep -q ^local0 /etc/syslog.conf

Durante la revisión, un compañero de trabajo sugirió que ^local0se citara porque ^significa "tubería" en el shell Bourne. Sorprendido por esta afirmación, traté de localizar cualquier referencia que mencionara esto. Nada de lo que encontré en Internet sugirió que esto fuera un problema.

Sin embargo, resulta que la implementación de bsh(que afirma ser el shell Bourne) en AIX 7 en realidad tiene este comportamiento:

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

Ninguna de las otras implementaciones de "shell Bourne" que intenté se comporta de esta manera (es decir, ^no se considera un metacarácter de shell en absoluto). Intenté shen CentOS (que es realmente bash) y shen FreeBSD (que no es bash). No tengo muchos otros sistemas para probar.

¿Se espera este comportamiento? ¿Qué proyectiles consideran ^un metacarácter de tubería?

Greg Hewgill
fuente
1
Sé que ^es un personaje de negación en zsh y también en el espacio regex. Como comentario separado, generalmente se recomienda usar comillas simples en la expresión grep para la portabilidad entre shells.
mkc
El shell bourne tenía un comportamiento extraño que todavía vemos en el código shell moderno, por ejemplo [ x"$foo" = x"bar" ].
jordanm
bshNo es el Bourne Shell. Se abusa del nombre de Bourne Shell solo en AIX. bshes más bien un shell introducido por mí en 1984 en H.Berhold AG en UNOS (el primer clon de UNIX). Tenga en cuenta que AIX no existía en 1984.
schily

Respuestas:

21

El ^personaje como sinónimo de |data de la concha de Thompson . Se introdujeron al mismo tiempo en Unix v4 y se mencionan juntos en la página del manual . Sven Mascheck menciona que ^"probablemente [se introdujo] por razones de conveniencia en las primeras terminales de mayúsculas", donde escribir |era "algo doloroso" .

El shell Thompson ya no existe, pero su sucesor, el shell Bourne, conserva la misma sintaxis (aunque su página de manual solo menciona |).

Los proyectiles sucesores como ash, bash y ksh solo se entienden |como el carácter de la tubería. No va a encontrar un shell Bourne real en las variantes de código abierto de Unix ya que durante mucho tiempo no hubo un lanzamiento de código abierto del shell Bourne. (Creo que OpenSolaris incluyó uno, pero no se adoptó en otro lugar ya que en ese momento estaba obsoleto por implementaciones más recientes).

La especificación Single Unix no menciona ^como un carácter especial, lo que significa que los shells POSIX deberían interpretarlo literalmente¹. No creo que haya habido una variante totalmente compatible con POSIX del shell Bourne (solo implementaciones independientes).

^es especial en zsh cuando la opción extendedglobestá habilitada, pero no en su modo de compatibilidad sh. En su modo predeterminado, se desvía de POSIX de muchas maneras.

Recomiendo citar ^en una expresión regular de todos modos para mayor claridad. Cite la expresión regular en un script independientemente de qué caracteres aparezcan en él.

Cept Excepto como el primer carácter de una expresión de paréntesis en un patrón comodín, donde !es el carácter de negación estándar, pero las implementaciones también pueden interpretarse ^de la misma manera.

Gilles 'SO- deja de ser malvado'
fuente
Gracias, todo el hilo TUHS de 2003 fue esclarecedor.
Greg Hewgill
Para completar, es posible que desee mencionar que ^es especial en fishdonde es un operador de redirección, rc/ esdonde es un operador de concatenación , o csh / tcsh / bash / zsh para la expansión del historial cuando es el primer carácter de la línea de comando.
Stéphane Chazelas
3

Sí, OpenSolaris incluye la fuente Bourne Shell, pero esa fuente no es portátil.

Una versión mantenida y altamente portátil de la fuente Bourne Shell se puede encontrar aquí en los schily-*.tar.bz2archivos.

Aquí está la parte relacionada de la fuente en cmd.c:

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

Verá, esto no está relacionado con un shell específico (por ejemplo, el shell Thompson) sino con el hecho de que en la década de 1970 todavía había terminales en mayúsculas.

astuto
fuente