Gli identificatori di comando e i nomi delle variabili hanno sintassi diverse. Un nome di variabile è limitato a caratteri alfanumerici e trattino basso, non inizia con una cifra. Un nome di comando, d'altra parte, può essere qualsiasi cosa che non contenga metacaratteri bash (e anche in questo caso, possono essere citati).
In bash, i nomi delle funzioni possono essere nomi di comandi, purché vengano analizzati come WORD senza virgolette. (Tranne che, per qualche motivo, non possono essere numeri interi.) Tuttavia, questa è un'estensione bash. Se la macchina di destinazione utilizza qualche altra shell (come trattino), potrebbe non funzionare, poiché la grammatica della shell standard Posix consente solo "NOME" nel modulo di definizione della funzione (e proibisce anche l'uso di parole riservate).
La domanda riguardava "le regole", a cui è stata data risposta in due modi diversi, ciascuno corretto in un certo senso, a seconda di ciò che si vuole chiamare "le regole". Solo per rimpolpare il punto di @rici secondo cui puoi inserire qualsiasi carattere in un nome di funzione, ho scritto un piccolo script bash per provare a controllare ogni carattere possibile (0-255) come nome di funzione, così come il secondo carattere di un nome di funzione:
#!/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
In realtà salto NUL (0x00), poiché è l'unico carattere che bash potrebbe obiettare alla ricerca nel flusso di input. L'output di questo script era:
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!
Nota che bash mi permette felicemente di nominare la mia funzione "[}{". Probabilmente il mio codice non è abbastanza rigoroso da fornire le regole esatte per la legalità nella pratica, ma dovrebbe dare un'idea di quale tipo di abuso sia possibile. Vorrei poter contrassegnare questa risposta "Solo per un pubblico adulto".
Dal manuale:
Shell Function Definitions
...
name () compound-command [redirection]
function name [()] compound-command [redirection]
name
è definito altrove:
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.
Quindi i trattini non sono validi. Eppure, sul mio sistema, funzionano...
$ bash --version
GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)