Les identificateurs de commande et les noms de variable ont des syntaxes différentes. Un nom de variable est limité aux caractères alphanumériques et au trait de soulignement, et ne commence pas par un chiffre. Un nom de commande, en revanche, peut être à peu près tout ce qui ne contient pas de métacaractères bash (et même dans ce cas, ils peuvent être entre guillemets).
Dans bash, les noms de fonction peuvent être des noms de commande, à condition qu'ils soient analysés comme un mot sans guillemets. (Sauf que, pour une raison quelconque, ils ne peuvent pas être des entiers.) Cependant, il s'agit d'une extension bash. Si la machine cible utilise un autre shell (tel que dash), cela peut ne pas fonctionner, car la grammaire standard du shell Posix n'autorise que "NAME" dans le formulaire de définition de fonction (et interdit également l'utilisation de mots réservés).
La question portait sur "les règles", à laquelle on a répondu de deux manières différentes, chacune correcte dans un certain sens, selon ce que vous voulez appeler "les règles". Juste pour étoffer le point de @rici selon lequel vous pouvez insérer n'importe quel caractère dans un nom de fonction, j'ai écrit un petit script bash pour essayer de vérifier chaque caractère possible (0-255) comme nom de fonction, ainsi que le deuxième caractère d'un nom de fonction :
#!/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
En fait, je saute NUL (0x00), car c'est le seul caractère que bash peut s'opposer à trouver dans le flux d'entrée. La sortie de ce script était :
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!
Notez que bash me permet heureusement de nommer ma fonction "[}{". Mon code n'est probablement pas assez rigoureux pour fournir les règles exactes de la légalité dans la pratique, mais il devrait donner une idée de la manière dont les abus sont possibles. J'aimerais pouvoir marquer cette réponse "Pour un public averti uniquement."
Du manuel :
Shell Function Definitions
...
name () compound-command [redirection]
function name [()] compound-command [redirection]
name
est défini ailleurs :
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.
Les traits d'union ne sont donc pas valides. Et pourtant, sur mon système, ils fonctionnent...
$ bash --version
GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)