Shell-gültige Funktionsnamen

12

Die Verwendung erweiterter Unicode-Zeichen ist (ohne Zweifel) für viele Benutzer nützlich.

Einfachere Shells (ash (busybox), dash) und ksh schlagen fehl mit:

tést() { echo 34; }

tést

Aber , , und scheinen es zu erlauben.

Mir ist bekannt, dass POSIX- gültige Funktionsnamen diese Definition von Namen verwenden . Das heißt dieser reguläre Ausdruck:

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

Im ersten Link heißt es jedoch auch:

Eine Implementierung kann andere Zeichen in einem Funktionsnamen als Erweiterung zulassen.

Die Fragen sind:

  • Wird dies akzeptiert und dokumentiert?
  • Wo?
  • Für welche Muscheln (falls vorhanden)?

Verwandte Fragen:
Ist es möglich, Sonderzeichen in einem Shell-Funktionsnamen zu verwenden?
Ich bin nicht daran interessiert, Metazeichen (>) in Funktionsnamen zu verwenden.

Namen von Upstart- und Bash-Funktionen, die "-" enthalten
Ich glaube nicht, dass ein Operator (Subtraktion "-") Teil eines Namens sein sollte.

Gemeinschaft
quelle
Sie werden vielleicht aliasetwas nachsichtiger sein. und so können Sie die Funktion mit einem richtigen, heruntergeknöpften Namen schreiben und dann einfach einen eleganteren Aliasnamen definieren, um die Funktion aufzurufen. in dashdort auch einige Sachen sind , können Sie mit tun $PATHund %func.
mikeserv

Antworten:

15

Da die POSIX-Dokumentation dies als Erweiterung zulässt, steht der Implementierung dieses Verhaltens nichts entgegen.

Ein einfacher Check (lief ein 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

zeigen , dass bash, zsh, yash, ksh93(welche in kshVerbindung mit in meinem System) pdkshund seine Ableitung ermöglichen Mehrbytes Zeichen als Funktionsnamen.

yash unterstützt von Anfang an Multibyte-Zeichen , daher ist es nicht verwunderlich, dass es funktioniert hat.

Die andere Dokumentation, auf die Sie verweisen können, ist ksh93:

Ein Leerzeichen ist ein Tabulator oder ein Leerzeichen. Ein Bezeichner ist eine Folge von Buchstaben, Ziffern oder Unterstrichen, die mit einem Buchstaben oder einem Unterstrich beginnen. Bezeichner werden als Komponenten von Variablennamen verwendet. Ein vname ist eine Folge von einem oder mehreren Bezeichnern, die durch ein getrennt sind. und optional mit einem vorangestellten .. Vnames werden als Funktions- und Variablennamen verwendet. Ein Wort ist eine Folge von Zeichen aus dem durch das aktuelle Gebietsschema definierten Zeichensatz , ausgenommen nicht in Anführungszeichen gesetzte Metazeichen.

So setzen Sie auf CGebietsschema:

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

machen es fehlgeschlagen.

cuonglm
quelle
poshist es nicht wert, in einer solchen Liste aufgeführt zu werden. Dies hängt von Linux-spezifischen Fehlern ab libcund funktioniert auf anderen Plattformen nicht.
Schily
Ich kann Ihre Behauptungen über die ksh93Verwendung eines selbst kompilierten ksh93 aus Originalquellen nicht wiederholen . Während ksh88offenbar Nicht-7-Bit-ASCII-Buchstaben für Funktionsnamen ksh93akzeptiert werden, scheint sie nur die Binärdatei von Ubuntu zu akzeptieren.
Schily
@schily ksh Ich habe in diesem Test die Binärdatei in Debian verwendet (so kann es mit einer unter Ubuntu
identisch sein
8

Beachten Sie, dass Funktionen denselben Namespace wie andere Befehle haben, einschließlich der Befehle im Dateisystem, die auf den meisten Systemen keine Beschränkung hinsichtlich der Zeichen oder sogar Bytes haben, die sie in ihrem Pfad enthalten können.

Während die meisten Shells die Charaktere ihrer Funktionen einschränken, gibt es keinen wirklich guten Grund, warum sie das tun würden. Das heißt, in diesen Shells gibt es Befehle, die Sie nicht durch eine Funktion ersetzen können.

zshund rcerlauben Sie alles für ihre Funktionsnamen, einschließlich einiger mit /und der leeren Zeichenfolge. zsherlaubt sogar NUL Bytes.

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

Ein einfacher Befehl in der Shell ist eine Liste von Argumenten, und das erste Argument wird verwendet, um den auszuführenden Befehl abzuleiten. Es ist also nur logisch, dass diese Argumente und Funktionsnamen die gleichen möglichen Werte haben und in zshArgumenten für integrierte Funktionen und Funktionen eine beliebige Bytefolge verwendet werden kann.

Hier gibt es keine Sicherheitslücke, da die Funktionen, die Sie (der Autor des Skripts) definieren, diejenigen sind, die Sie aufrufen.

Sicherheitsprobleme treten möglicherweise auf, wenn die Analyse von der Umgebung beeinflusst wird, z. B. bei Shells, bei denen die gültigen Namen für Funktionen vom Gebietsschema abhängen.

Stéphane Chazelas
quelle
Man kann auch Spiele in der Bash spielen, beginnend mit function /bin/sh { echo "$0: $FUNCNAME: Permission denied"; return 126; }und potentiell nützliche Dinge auch mit Funktionen genannt --, //, @oder %usw.
mr.spuratic
Aber neigen Shells nicht dazu, eine Hashtabellensuche zu umgehen, wenn /sie in einem Namen gefunden werden? und eine Funktion ist nicht nur ein ausführbarer Name - ihr Code. Ich würde denken, dass eine einfache Implementierung auf eine Menge von Analyseproblemen stoßen könnte, wenn die gespeicherten Funktionsnamen Metazeichen enthalten.
mikeserv
Ja, ich bin mir der Unfähigkeit von bash bewusst, Nullen in vars zu enthalten, die vernünftigerweise auf Funktionsnamen erweitert werden könnten. Ich habe kein konkretes Beispiel, aber ich bin der Meinung, dass dieses Spiel, bei dem fast alles für Namen zugelassen wird, eher eine potenzielle Sicherheitsverletzung darstellt als eine "einfache Art zu arbeiten". Ich hoffe ich irre mich