Caracteres de nombre de función válidos de shell

13

El uso de caracteres Unicode extendidos es (sin duda) útil para muchos usuarios.

Los shells más simples (ash (busybox), dash) y ksh fallan con:

tést() { echo 34; }

tést

Pero , , y parecen permitirlo.

Soy consciente de que los nombres de función válidos POSIX utilizan esta definición de nombres . Eso significa esta expresión regular:

[a-zA-Z_][a-zA-Z0-9_]*

Sin embargo, en el primer enlace también se dice:

Una implementación puede permitir otros caracteres en el nombre de una función como una extensión.

Las preguntas son:

  • ¿Es esto aceptado y documentado?
  • ¿Dónde?
  • ¿Para qué conchas (si las hay)?

Preguntas relacionadas: ¿
Es posible usar caracteres especiales en un nombre de función de shell?
No estoy interesado en usar metacaracteres (>) en los nombres de funciones.

Nombres de funciones de arranque y bash que contienen “-”
No creo que un operador (resta "-") deba ser parte de un nombre.

Comunidad
fuente
puede aliasser un poco más indulgente. para que pueda escribir la función con un nombre apropiado y abotonado, y luego simplemente definir un alias con más estilo para llamar a la función. en dashtambién hay algunas cosas que puede hacer con $PATHy %func.
mikeserv

Respuestas:

16

Dado que la documentación POSIX lo permite como una extensión, no hay nada que impida la implementación de ese comportamiento.

Una verificación simple (corrió zsh):

$ for shell in /bin/*sh 'busybox sh'; do
    printf '[%s]\n' $shell
    $=shell -c 'á() { :; }'
  done
[/bin/ash]
/bin/ash: 1: Syntax error: Bad function name
[/bin/bash]
[/bin/dash]
/bin/dash: 1: Syntax error: Bad function name
[/bin/ksh]
[/bin/lksh]
[/bin/mksh]
[/bin/pdksh]
[/bin/posh]
/bin/posh: á: invalid function name
[/bin/yash]
[/bin/zsh]
[busybox sh]
sh: syntax error: bad function name

demostrar que bash, zsh, yash, ksh93(que kshhay enlaces en mi sistema), pdkshy su derivación permite múltiples bytes caracteres como nombre de la función.

yash está diseñado para admitir caracteres multibyte desde el principio, por lo que no sorprende que haya funcionado.

La otra documentación que puede consultar es ksh93:

Un espacio en blanco es una pestaña o un espacio. Un identificador es una secuencia de letras, dígitos o guiones bajos que comienzan con una letra o guión bajo. Los identificadores se usan como componentes de nombres de variables. Un vname es una secuencia de uno o más identificadores separados por a. y opcionalmente precedido por un .. Vnames se utilizan como nombres de funciones y variables. Una palabra es una secuencia de caracteres del conjunto de caracteres definido por la configuración regional actual , excluyendo los metacaracteres no citados.

Entonces configurando a Clocale:

$ export LC_ALL=C
$ á() { echo 1; }
ksh: á: invalid function name

hazlo fallar.

Cuonglm
fuente
poshNo vale la pena ser incluido en esa lista. Depende de errores específicos de Linux libcy no funcionará en otras plataformas.
schily 01 de
No puedo repetir sus afirmaciones sobre el ksh93uso de un ksh93 autocompilado de fuentes originales. Si bien ksh88parece aceptar letras no ASCII de 7 bits para los nombres de funciones, solo el ksh93binario de Ubuntu parece aceptarlas.
schily
@schily KSH I utilizado en esta prueba es el binario en Debian (lo que puede ser el mismo con uno en Ubuntu)
cuonglm
9

Tenga en cuenta que las funciones comparten el mismo espacio de nombres que otros comandos, incluidos los comandos en el sistema de archivos, que en la mayoría de los sistemas no tienen limitación en los caracteres o incluso bytes que pueden contener en su ruta.

Entonces, si bien la mayoría de los shells restringen los caracteres de sus funciones, no hay una buena razón por la que lo hagan. Eso significa que en esos shells, hay comandos que no puedes reemplazar con una función.

zshy rcpermita cualquier cosa para sus nombres de función, incluidos algunos con /y la cadena vacía. zshincluso permite bytes NUL.

$ zsh
$ $'\0'() echo nul
$ ^@
nul
$ ""() uname
$ ''
Linux
$ /bin/ls() echo test
$ /bin/ls
test

Un comando simple en shell es una lista de argumentos, y el primer argumento se usa para derivar el comando a ejecutar. Por lo tanto, es lógico que esos argumentos y nombres de funciones compartan los mismos valores posibles y en los zshargumentos a las funciones y funciones incorporadas pueden ser cualquier secuencia de bytes.

No hay ningún problema de seguridad aquí, ya que las funciones que usted (el autor del script) define son las que invoca.

Donde puede haber problemas de seguridad es cuando el análisis afecta al entorno, por ejemplo, con shells donde los nombres válidos para las funciones se ven afectados por la configuración regional.

Stéphane Chazelas
fuente
Uno puede jugar a juegos de fiesta también, a partir de function /bin/sh { echo "$0: $FUNCNAME: Permission denied"; return 126; }, y potencialmente cosas útiles también con funciones con nombre --, //, @o %etc
mr.spuratic
pero ¿no tienden a pasar por alto las búsquedas de tablas hash cuando /se encuentran en un nombre? y una función no es solo un nombre ejecutable: su código. Creo que una implementación simple podría encontrar muchos problemas de análisis si los nombres de las funciones almacenadas incluyen metacaracteres.
mikeserv
Sí, soy consciente de la incapacidad de bash para contener nulos en vars, que podría extenderse razonablemente a los nombres de funciones. No tengo un ejemplo específico, pero creo que este juego de permitir casi cualquier cosa para los nombres es más una violación potencial de seguridad que una "forma fácil de trabajar". Espero estar equivocado