Antworten:
$(command)
ist "Befehlsersetzung". Wie Sie zu verstehen scheinen, führt es das aus command
, erfasst die Ausgabe und fügt sie in die Befehlszeile ein, die das enthält $(…)
. z.B,
$ ls -ld $(date +%B).txt
-rwxr-xr-x 1 Noob Noob 867 Jul 2 11:09 July.txt
${parameter}
ist "Parametersubstitution". Viele Informationen finden Sie in der Manpage der Shell, bash (1) , unter der Überschrift „ Parameter Expansion “:
${parameter}
Der Wert von parameter wird ersetzt. Die geschweiften Klammern sind erforderlich, wenn parameter ein Positionsparameter mit mehr als einer Ziffer ist oder wenn auf parameter ein Zeichen folgt, das nicht als Teil seines Namens interpretiert werden soll.
Informationen zu Positionsparametern finden Sie weiter unten unter „ Positionsparameter “. Am häufigsten wird, wie in den anderen Antworten gezeigt,
parameter
ein Variablenname verwendet. Mit dem ${…}
am Ende des obigen Abschnitts angegebenen Formular können Sie den Wert einer Variablen (dh ) abrufen und dieser unmittelbar einen Buchstaben, eine Ziffer oder einen Unterstrich hinzufügen:$variable_name
$ animal = cat $ Echo $ Tiere # Keine Variable wie "Tiere". $ echo $ {animal} s Katzen $ echo $ animal_food # Keine Variable wie "animal_food". $ echo $ {animal} _food Katzenfutter
Sie können dies auch mit Anführungszeichen tun:
$ echo "$ animal" s Katzen
Als Übung zu Optionen können Sie auch eine zweite Variable verwenden:
$ plural = s $ echo $ animal $ plural Katzen
Dies ist jedoch nur Schritt 1. Der nächste Absatz in der Manpage ist interessant, wenn auch etwas kryptisch:
Wenn das erste Zeichen des Parameters
ein Ausrufezeichen ( !
) ist, wird eine variable Indirektionsebene eingeführt. Bash verwendet den Wert der aus dem Rest des Parameters gebildeten Variablen
als Namen der Variablen. Diese Variable wird dann erweitert und dieser Wert wird im Rest der Ersetzung verwendet, anstatt der Wert des Parameters selbst. Dies wird als indirekte Expansion bezeichnet .
… (Ausnahmen) …
Das Ausrufezeichen muss unmittelbar nach der linken Klammer stehen, um die Indirektion einzuführen.
Ich bin mir nicht sicher, wie ich das klarer machen kann, außer am Beispiel:
$ animal = cat $ Echo $ Tier Katze $ cat = tabby $ echo $ cat tabby $ echo $ {! animal} Tabby # Wenn $ Tier ist „cat“ , dann $ {!} Tier ist $ cat , das heißt, „Tabby“
Nennen wir diesen Schritt 1½. Es gibt viele interessante Dinge, die Sie als Schritt 2 tun können:
$ animal = cat $ echo $ {# animal} 3 # Stringlänge $ echo $ {animal / at / ow} Kuh # Substitution
Sie können nichts ohne die {
... }
Klammern tun .
Positionsparameter
Betrachten Sie dieses künstliche Beispiel:
$ cat myecho.sh echo $ 1 $ 2 $ 3 $ 4 $ 5 $ 6 $ 7 $ 8 $ 9 $ 10 $ 11 $ 12 $ 13 $ 14 $ 15 $ ./myecho.sh Hey diddle diddle, Die Katze und die Geige, Die Kuh sprang über den Mond. Hey diddle diddle, Die Katze und die Geige, Die Hey0 Hey1 Hey2 Hey3 Hey4 Hey5
weil die Shell nicht versteht $10
, $11
usw. Es behandelt, $10
als ob es wäre ${1}0
. Aber es versteht ${10}
, ${11}
usw., wie in der Manpage erwähnt ("ein Positionsparameter mit mehr als einer Ziffer").
Aber schreibe keine solchen Skripte. Es gibt bessere Möglichkeiten, mit langen Argumentlisten umzugehen.
Das Obige (zusammen mit vielen weiteren Formen von Konstrukten) wird ausführlicher in der Manpage der Shell, bash (1), behandelt .${parameter…something_else}
Eine Anmerkung zu Anführungszeichen
Beachten Sie, dass Sie Shell-Variablen immer in Anführungszeichen setzen sollten, es sei denn, Sie haben einen guten Grund, dies nicht zu tun , und Sie sind sicher , dass Sie wissen, was Sie tun. Während geschweifte Klammern wichtig sein können, sind sie im Gegensatz dazu nicht so wichtig wie Anführungszeichen.
$ filename = "Kinderreim.txt" $ ls -ld $ {filename} ls: kann nicht auf den Kindergarten zugreifen: Keine solche Datei oder kein solches Verzeichnis ls: kann nicht auf rhyme.txt zugreifen: Keine solche Datei oder kein solches Verzeichnis $ ls -ld "$ filename" -rwxr-xr-x 1 Noob Noob 5309 2. Juli 11:09 Kinderreim.txt
Dies gilt auch für Positionsparameter (z. B. "$1"
Befehlszeilenargumente) und auch für die Befehlssubstitution:
$ ls -ld $ (Datum "+% B% Y"). txt ls: Kein Zugriff auf July: Keine solche Datei oder kein solches Verzeichnis ls: kann nicht auf 2015.txt zugreifen: Keine solche Datei oder Verzeichnis $ ls -ld "$ (Datum" +% B% Y "). txt" -rwxr-xr-x 1 Noob Noob 687 Jul 2 11:09 July 2015.txt
Eine kurze Abhandlung über die Interaktion zwischen Anführungszeichen und ... finden Sie unter Bash-Anführungszeichen ohne Befehlsersetzung .$(
)
!
.
${!animal}
bezieht sich eigentlich auf die Variable $cat
anstatt auf den Wert cat." Ja, das ist genau der Punkt. "Wie wird / at ein" c "in echo $ {animal / at / ow}?" Huh? / at wird nicht "c"; "Cat" wird "cow", wenn "at" durch "ow" ersetzt wird.
In Ihrem Beispiel sind $ var und $ {var} identisch. Geschweifte Klammern sind jedoch nützlich, wenn Sie die Variable in einer Zeichenfolge erweitern möchten:
$ string=foo
$ echo ${string}bar
foobar
$ echo $stringbar
$
Somit bieten die geschweiften Klammern eine Möglichkeit, die Variable zu ersetzen, um den Namen der neuen Variablen zu erhalten, die selbst ersetzt werden soll.
Ich sehe es normalerweise häufiger in Streichern. So etwas funktioniert nicht:
var="a"
echo "$varRAW_STRING"
Aber das wird:
var="a"
echo "${var}RAW_STRING"
Wie Sie richtig sagten, $()
wird verwendet, um einen Befehl auszuführen:
dir_contents=$(ls)
Sie können auch Backticks verwenden, aber ich finde die $()
vielseitiger. Zum einen können Backticks nicht (einfach) verschachtelt werden.
date_directory=`ls `date '+%Y-%m-%d'`` # Makes no sense
date_directory=$(ls $(date '+%Y-%m-%d')) # Much better
date_directory=`ls \`date '+%Y-%m-%d'\``
. Aber es ist schrecklich hässlich. $(…)
ist viel klarer und einfacher zu bedienen.
`…`
war die (einzige) Syntax für die Befehlsersetzung vor Jahren $(…)
erfunden worden, so müssen Sie sich nichts vorstellen - die Leute haben es getan.
${
variable_name
}