Caratteri di nome funzione shell validi


13

L'uso di caratteri Unicode estesi è (senza dubbio) utile per molti utenti.

Le shell più semplici (ash (busybox), dash) e ksh non funzionano con:

tést() { echo 34; }

tést

Ma , , e sembrano permetterlo.

Sono consapevole che i nomi di funzioni valide POSIX utilizzano questa definizione di nomi . Ciò significa che questa regex:

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

Tuttavia, nel primo link si dice anche:

Un'implementazione può consentire altri caratteri in un nome di funzione come estensione.

Le domande sono:

  • Questo è accettato e documentato?
  • Dove?
  • Per quali shell (se ce ne sono)?

Domande correlate: è
possibile utilizzare caratteri speciali nel nome di una funzione shell?
Non mi interessa usare i meta-caratteri (>) nei nomi delle funzioni.

Nomi di funzioni upstart e bash contenenti “-”
Non credo che un operatore (sottrazione "-") dovrebbe far parte di un nome.


potresti scoprire aliasdi essere un po 'più indulgente. e così puoi scrivere la funzione con un nome appropriato abbottonato e quindi definire un alias con un nome più elegante per chiamare la funzione. in dashc'è anche alcune cose si può fare con $PATHe %func.
mikeserv,

Risposte:


16

Poiché la documentazione POSIX lo consente come estensione, non c'è nulla che impedisca l'implementazione da quel comportamento.

Un semplice controllo (eseguito 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

dimostrano che bash, zsh, yash, ksh93(che kshcollegato al mio sistema), pdkshe la sua derivazione consentire multi-byte caratteri come nome della funzione.

yash è progettato per supportare i personaggi multibyte sin dall'inizio, quindi non c'è da stupirsi che abbia funzionato.

L'altra documentazione a cui puoi fare riferimento è ksh93:

Uno spazio vuoto è una scheda o uno spazio. Un identificatore è una sequenza di lettere, cifre o caratteri di sottolineatura che iniziano con una lettera o un trattino basso. Gli identificatori vengono utilizzati come componenti di nomi di variabili. Un vname è una sequenza di uno o più identificatori separati da a. e facoltativamente preceduto da un .. Vnames sono usati come nomi di funzioni e variabili. Una parola è una sequenza di caratteri del set di caratteri definito dalla locale corrente , esclusi i metacaratteri non quotati.

Quindi impostando le impostazioni Clocali:

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

fallo fallire.


poshnon vale la pena essere elencati in tale elenco. Dipende da bug specifici di Linux libce non funzionerà su altre piattaforme.
schily

Non posso ripetere le tue affermazioni ksh93sull'uso di un ksh93 compilato da fonti originali. Mentre ksh88sembra accettare lettere non 7-Bit-ASCII per nomi di funzioni, solo il ksh93binario di Ubuntu sembra accettarle.
schily

@schily ksh che ho usato in questo test è il binario in Debian (quindi potrebbe essere lo stesso con uno su Ubuntu)
cuonglm

9

Si noti che le funzioni condividono lo stesso spazio dei nomi di altri comandi, inclusi i comandi nel file system, che sulla maggior parte dei sistemi non hanno limiti sui caratteri o sui byte che possono contenere nel loro percorso.

Quindi, mentre la maggior parte delle shell limitano i caratteri delle loro funzioni, non esiste una vera ragione per cui lo farebbero. Ciò significa che in quelle shell, ci sono comandi che non è possibile sostituire con una funzione.

zshe rcconsentire qualsiasi cosa per i loro nomi di funzione inclusi alcuni con /e la stringa vuota. zshconsente anche byte NUL.

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

Un semplice comando nella shell è un elenco di argomenti e il primo argomento viene utilizzato per derivare il comando da eseguire. Quindi, è logico che quegli argomenti e nomi di funzioni condividano gli stessi valori possibili e negli zshargomenti di builtin e funzioni può essere qualsiasi sequenza di byte.

Non ci sono problemi di sicurezza qui come le funzioni che tu (l'autore dello script) definisci sono quelle che invochi.

Dove possono esserci problemi di sicurezza è quando l'analisi è influenzata dall'ambiente, ad esempio con shell in cui i nomi validi per le funzioni sono influenzati dalle impostazioni locali.


Si può giocare in bash troppo, a cominciare function /bin/sh { echo "$0: $FUNCNAME: Permission denied"; return 126; }, e potenzialmente cose utili anche con funzioni denominate --, //, @o %ecc
mr.spuratic

ma le shell non tendono a bypassare una ricerca nella tabella hash quando /viene trovata in un nome? e una funzione non è solo un nome eseguibile - il suo codice. penso che una semplice implementazione potrebbe incontrare molti problemi di analisi se i nomi delle sue funzioni memorizzate includessero metacaratteri.
Mikeserv,

Sì, sono consapevole dell'incapacità di bash di contenere valori nulli in vars, che potrebbero essere ragionevolmente estesi ai nomi delle funzioni. Non ho un esempio specifico, ma credo che questo gioco di consentire praticamente qualsiasi cosa per i nomi sia più una potenziale violazione della sicurezza che un "modo semplice di lavorare". Spero di sbagliarmi.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.