Bash/Parameterexpansion

Aus Foxwiki

Parameterexpansion

Folgt einem Dollarzeichen $ ein Variablenname oder eine öffnende geschweifte Klammer ${...}, so spricht man von einer Variablen- bzw. Parameterexpansion.

Die geschweiften Klammern dienen zur Gruppierung und sind bei skalaren Variablen, die nicht per Parameterexpansion behandelt werden sollen, nicht notwendig.

Beginnen wir mit einem Beispiel der Expansion einer skalaren Variable ohne Parameterexpansion:

var=user
var2=~$var
echo $var2
~user
eval echo $var2
/home/user

Bemerkung

  • Das Beispiel verdeutlicht die Reihenfolge der Auflösung bei Zuweisung eines Wertes an "var2".
  • Im ersten Schritt ist die Tilde nicht auflösbar, deshalb geht sie unverändert in "var2" ein.
  • In einem zweiten Schritt expandiert dann der Inhalt von "var", so dass "var2" nun "~user" beinhaltet.
  • Um den Expansionsmechnismus zu demonstrieren, wurde eine erneute Bewertung von "var2" erzwungen (eval); nun expandiert "~user" zum Heimatverzeichnis "/home/user".
  • Ist das erste Zeichen eines Parameters das Ausrufezeichen, so handelt es sich um eine indirekte Expansion.
  • Die Bash ersetzt den Ausdruck jetzt nicht mehr durch den Inhalt der Variablen, sondern betrachtet den Inhalt als den Namen einer Variablen, zu deren Inhalt nun expandiert wird.

Ein Beispiel erklärt den Sachverhalt wohl deutlicher, als es Worte vermögen:

var=user
var2=var
echo $var2
var
echo ${!var2}
user
  • Die weiteren Mechanismen zur Parameterexpansion manipulieren den Inhalt von Variablen.
  • Die Beispiele werden zeigen, dass diese Form der Substitution vor allem für die Shellprogrammierung von immensem Nutzen ist und genau dort werden sie uns wieder begegnen.
  • »parameter« bezeichnet nachfolgend den Variablennamen und »word« steht entweder für eine Zeichenkette oder für eine Variable, die selbst wieder eine Parameter-, Kommando, Tildeexpansion oder eine arithmetische Berechnung beinhalten kann.

Variablen-Substitution

  • Unter Variablen-Substitution versteht man verschiedene Methoden um die Inhalte von Variablen zu benutzen.
  • Das umfasst sowohl die einfache Zuweisung eines Wertes an eine Variable, als auch einfache Möglichkeiten zur Fallunterscheidung. In den fortgeschritteneren Shell-Versionen (bash, ksh)existieren sogar Möglichkeiten, auf Substrings von Variableninhalten zuzugreifen.
  • In der Standard-Shell benutzt man für solche Zwecke üblicherweise den Stream-Editor sed. Einleitende Informationen dazu finden sich im Kapitel über die Mustererkennung).
  • Die folgenden Mechanismen stehen in der Standard-Shell bereit, um mit Variablen zu hantieren. Bei allen Angaben ist der Doppelpunkt optional.
  • Wenn er aber angegeben wird, muss die Variable einen Wert enthalten.
Variable=Wert Setzt die Variable auf den Wert.
${Variable} Nutzt den Wert von Variable. Die Klammern müssen nicht mit angegeben werden, wenn die Variable von Trennzeichen umgeben ist.
${Variable:-Wert} Nutzt den Wert von Variable. Falls die Variable nicht gesetzt ist, wird der Wert benutzt.
${Variable:=Wert} Nutzt den Wert von Variable. Falls die Variable nicht gesetzt ist, wird der Wert benutzt, und Variable erhält den Wert.
${Variable:?Wert} Nutzt den Wert von Variable. Falls die Variable nicht gesetzt ist, wird der Wert ausgegeben und die Shell beendet. Wenn kein Wert angegeben wurde, wird der Text parameter null or not set ausgegeben.
${Variable:+Wert} Nutzt den Wert, falls die Variable gesetzt ist, andernfalls nichts.
Beispiele
$ h=hoch r=runter l= Weist den drei Variablen Werte zu, wobei l einen leeren Wert erhält.
$ echo ${h}sprung Gibt hochsprung aus. Die Klammern müssen gesetzt werden, damit h als Variablenname erkannt werden kann.
$ echo ${h-$r} Gibt hoch aus, da die Variable h belegt ist. Ansonsten würde der Wert von r ausgegeben.
$ echo ${tmp-`date`} Gibt das aktuelle Datum aus, wenn die Variable tmp nicht gesetzt ist. (Der Befehl date gibt das Datum zurück)
$ echo ${l=$r} Gibt runter aus, da die Variable l keinen Wert enthält. Gleichzeitig wird l der Wert von r zugewiesen.
$ echo $l Gibt runter aus, da l jetzt den gleichen Inhalt hat wie r.

Expansion vor der Wertzuweisung an eine Variable

  • Bevor ein Wert einer Variablen zugewiesen wird, versucht die Bash diesen Wert nach bestimmten Regeln zu substituieren.
  • Dabei durchläuft die Bash folgende Schritte in beschriebener Reihenfolge:
  1. Tildeexpansion
  2. Parameter- und Variablenexpansion
  3. Kommandosubstitution
  4. Arithmetische Substitution
  5. Entfernen der »Quoting«-Zeichen
  • Erst jetzt erfolgt die tatsächliche Zuweisung an die Variable.
  • Was sich hinter den einzelnen Expansionen verbirgt, soll im Anschluss an diesen Abschnitt betrachtet werden.

Das "$" Zeichen leitet eine Parameterexpansion, Kommandosubstitution oder eine arithmetische Expansion ein. Der Parametername kann in Klammern gesetzt werden, um zu verhindern, dass direkt darauf folgende Zeichen als Teil des Namens interpretiert werden.

Wenn Klammern benutzt werden ist die treffende Schließende Klammer die erste "}", die nicht durch einen maskiert wurde und sich nicht innerhaltb einer eingebetteten arithmetischen Expansion, eine Komanndosubstitution oder einer Parameter-Expansion befindet.

The basic form of parameter expansion is "${PARAMETER}".

The value of "PARAMETER" is substituted.

The braces are required when "PARAMETER" is a positional parameter with more than one digit, or when "PARAMETER" is followed by a character that is not to be interpreted as part of its name.

If the first character of "PARAMETER" is an exclamation point, Bash uses the value of the variable formed from the rest of "PARAMETER" as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of "PARAMETER" itself.

This is known as indirect expansion.

You are certainly familiar with straight parameter expansion, since it happens all the time, even in the simplest of cases, such as the one above or the following:

$ echo $SHELL
/bin/bash

The following is an example of indirect expansion:

$ echo ${!N*}
NTPPORT NNTPSERVER NPX_PLUGIN_PATH

Note that this is not the same as echo $N*. The following construct allows for creation of the named variable if it does not yet exist:

${VAR:=value} 

Example

echo $DIRKWAGNER
echo ${DIRKWAGNER:=Dirkwagner}
Dirkwagner

Special parameters, among others the positional parameters, may not be assigned this way, however.