Separate Namespaces für Funktionen und Variablen in POSIX-Shells

Separate Namespaces für Funktionen und Variablen in POSIX-Shells

In Dash scheinen Funktionen und Variablen in separaten Namespaces zu existieren:

fn(){
    fn="hello world"
}
fn; echo "The value is $fn!" #prints: The value is hello world!
fn; echo "The value is $fn!" #prints: The value is hello world!
#the fn variable doesn't conflict with the fn function

Handelt es sich hierbei um eine Dash-spezifische Funktion oder eine POSIX-Garantie?

Antwort1

Eine Garantie:

2.9.5 Funktionsdefinitionsbefehl

Eine Funktion ist ein benutzerdefinierter Name, der als einfacher Befehl verwendet wird, um einen zusammengesetzten Befehl mit neuen Positionsparametern aufzurufen. Eine Funktion wird mit einem „Funktionsdefinitionsbefehl“ definiert.[...]

Die Funktion heißt fname. Die Anwendung muss sicherstellen, dass es sich um einen Namen handelt (siehe XBD-Name) und nicht um den Namen eines speziellen integrierten Dienstprogramms. Eine Implementierung kann als Erweiterung andere Zeichen in einem Funktionsnamen zulassen.Die Implementierung muss separate Namensräume für Funktionen und Variablen beibehalten.

Antwort2

Variablen und Funktionen befinden sich in Dash in unterschiedlichen Namespaces und dies wird auch angegeben durchPOSIX:

Die Implementierung muss separate Namensräume für Funktionen und Variablen beibehalten.

Darüber hinaus haben Variablen standardmäßig einen globalen Gültigkeitsbereich. Einige Shells (z. B. Bash, Ksh und Zsh) bieten das localSchlüsselwort, um Variablen in einer Funktion nur mit lokalem Gültigkeitsbereich zu deklarieren.

Also ja, das Verhalten, das Sie sehen, wird durch POSIX garantiert.

POSIX hat nichtstandardisiert local,noch:

Die Beschreibung von Funktionen in einem frühen Vorschlag basierte auf der Vorstellung, dass sich Funktionen wie Miniatur-Shell-Skripte verhalten sollten, d. h.mit Ausnahme der Freigabe von Variablen, die meisten Elemente einer Ausführungsumgebung sollten sich so verhalten, als wären sie eine neue Ausführungsumgebung, [..]

[..] Lokale Variablen innerhalb einer Funktion wurden in einem anderen frühen Vorschlag berücksichtigt und einbezogen (gesteuert durch das spezielle integrierte local), aberwurden entferntweil sie nicht in das einfache Modell passen, das für Funktionen entwickelt wurde, und weil es einige Widerstände gegen das Hinzufügen eines weiteren neuen speziellen integrierten Elements gab, das nicht Teil der historischen Praxis war. Implementierungen sollten den Bezeichner local(sowie typeset, wie in der KornShell verwendet) reservieren, falls dieser lokale Variablenmechanismus in einer zukünftigen Version dieses Standards übernommen wird.

(Hervorhebung von mir)

verwandte Informationen