Variablenerweiterung in Bash

Variablenerweiterung in Bash

Ich habe die folgenden Befehle ausprobiert

variable='one|name'
echo $variable

Die Ausgabe ist

one|name

während echo one|nameein Fehler ausgegeben wird No command 'name' found. Das ist sinnvoll, da Bash es |als Pipe behandelt und versucht, den Befehl namemit oneals Eingabe auszuführen.

Aber warum wird echo $variablegedruckt one|name? Sollte es nach der Parameter- und Variablenerweiterung nicht gleichwertig sein mit echo one|name?

Ausführung:

GNU bash, version 4.3.11(1)-release (i686-pc-linux-gnu)

Antwort1

Nein, das sollte es nicht, dennbash den Befehl ausführen.

Wenn Sie eingeben echo one|name, bashwird der Befehl analysiert und |als Pipe-Token behandelt, sodass |eine Pipeline ausgeführt werden kann.

Wenn Sie eingeben , wird der Befehl in zwei Teile zerlegt, echo $variableda die Token-Analyse vor der Variablenerweiterung erfolgt, und . Danach wird die Variablenerweiterung durchgeführt, die zu erweitert wird . In diesem Fall ist ein String, ist ein Teil eines Strings und kann nicht als Pipe-Token behandelt werden (natürlichbashecho$variable$variableone|nameone|name|die Token-Erkennungsphrasewurde durchgeführt). Das einzige, was besonders sein kann, wenn IFSdie Variable enthält |, bashwird als Trennzeichen verwendet, |um die Feldaufteilung durchzuführen:

$ variable='one|name'
$ IFS='|'
$ echo $variable
one name

Antwort2

Der Grund liegt in der Art und Weise, wie Bashdie Variable erweitert wird.

Anstatt die Variable auf zu erweitern, one|namewird sie auf erweitert "one|name". Da der Wert hier in Anführungszeichen steht, wird er als Zeichenfolge und nicht als Befehl behandelt.

Unten sehen Sie die straceAusgabe des Befehls, die zeigt, wie der Befehl erweitert wird.

$ variable='one|name'
$ strace echo $variable 
execve("/bin/echo", ["echo", "one|name"], [/* 33 vars */]) = 0
brk(0)                                  = 0x9cc7000

Antwort3

Die Anführungszeichen sind Teil der von Ihnen erstellten Zeichenfolge.

Wenn du. .. getan hast

variable=one|name
echo $variable

das Ergebnis wäre wie erwartet. Aber das geht nur in einem Skript (danke für den hilfreichen Kommentar).

verwandte Informationen