GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cuáles son las reglas para los identificadores válidos (por ejemplo, funciones, vars, etc.) en Bash?

Los identificadores de comandos y los nombres de variables tienen sintaxis diferentes. Un nombre de variable está restringido a caracteres alfanuméricos y guiones bajos, sin comenzar con un dígito. Un nombre de comando, por otro lado, puede ser casi cualquier cosa que no contenga metacaracteres bash (e incluso entonces, se pueden citar).

En bash, los nombres de las funciones pueden ser nombres de comandos, siempre que se analicen como una PALABRA sin comillas. (Excepto que, por alguna razón, no pueden ser números enteros). Sin embargo, esa es una extensión bash. Si la máquina de destino usa algún otro shell (como guión), es posible que no funcione, ya que la gramática de shell estándar de Posix solo permite "NOMBRE" en el formulario de definición de función (y también prohíbe el uso de palabras reservadas).


La pregunta era sobre "las reglas", a la que se ha respondido de dos maneras diferentes, cada una correcta en algún sentido, dependiendo de lo que se quiera llamar "las reglas". Solo para dar cuerpo al punto de @rici de que puedes empujar cualquier carácter en el nombre de una función, escribí un pequeño script de bash para tratar de verificar todos los caracteres posibles (0-255) como nombre de función, así como el segundo carácter de un nombre de función:

#!/bin/bash
ASCII=( nul soh stx etx eot enq ack bel bs tab nl vt np cr so si dle \
            dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us sp )

for((i=33; i < 127; ++i)); do
    printf -v Hex "%x" $i

    printf -v Chr "\x$Hex"
    ASCII[$i]="$Chr"
done
ASCII[127]=del
for((i=128; i < 256; ++i)); do
    ASCII[$i]=$(printf "0X%x" $i)
done

# ASCII table is now defined

function Test(){
    Illegal=""
    for((i=1; i <= 255; ++i)); do
        Name="$(printf \\$(printf '%03o' $i))"
        eval "function $1$Name(){ return 0; }; $1$Name ;" 2>/dev/null
        if [[ $? -ne 0 ]]; then
            Illegal+=" ${ASCII[$i]}"
            #        echo Illegal: "${ASCII[$i]}"
        fi
    done
    printf "Illegal: %s\n" "$Illegal"
}
echo "$BASH_VERSION"
Test
Test "x"

# can we really do funky crap like this?
function [}{(){
   echo "Let me take you to, funkytown!"
}
[}{    # why yes, we can!
# though editor auto-indent modes may punish us

De hecho, omito NUL (0x00), ya que ese es el único carácter que bash puede oponerse a encontrar en el flujo de entrada. El resultado de este script fue:

4.4.0(1)-release
Illegal:  soh tab nl sp ! " # $ % & ' ( ) * 0 1 2 3 4 5 6 7 8 9 ; < > \ ` { | } ~ del
Illegal:  soh " $ & ' ( ) ; < > [ \ ` | del
Let me take you to, funkytown!

Tenga en cuenta que bash felizmente me permite nombrar mi función "[}{". Probablemente mi código no sea lo suficientemente riguroso como para proporcionar las reglas exactas para la legalidad en la práctica, pero debería dar una idea de qué tipo de abuso es posible. Desearía poder marcar esta respuesta como "Solo para audiencias maduras".


Del manual:

   Shell Function Definitions
       ...
       name () compound-command [redirection]
       function name [()] compound-command [redirection]

name se define en otra parte:

       name   A  word  consisting  only  of alphanumeric characters and under‐
              scores, and beginning with an alphabetic character or an  under‐
              score.  Also referred to as an identifier.

Así que los guiones no son válidos. Y, sin embargo, en mi sistema, funcionan...

$ bash --version
GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)

Linux
  1. ¿Funciones en variables de Shell?

  2. 7zip, Xz, Gzip, Tar, etc., ¿cuáles son las diferencias?

  3. ¿Cuáles son los beneficios de CloudLinux?

  4. Alcance variable para scripts y funciones bash shell en el script

  5. ¿Cuál es el uso de $# en Bash?

Funciones bash

Shell Scripting Parte V:Funciones en Bash

El Bash FOR Loop explicado y simplificado

¿Cuáles son las convenciones de llamada para las llamadas del sistema UNIX y Linux (y funciones de espacio de usuario) en i386 y x86-64?

¿Cuáles son las funciones del BIOS mientras se ejecuta el sistema operativo?

¿Cuáles son las diferentes formas de establecer permisos de archivo, etc. en gnu/linux?