Ich versuche, eine Zeichenfolge mit einem Platzhalter und einer Sammlung von Erweiterungen in geschweiften Klammern zu erweitern. Nichts scheint zu funktionieren, wie das folgende Beispiel zeigt. die Variable firstList
expandiert in Ordnung, aber weder secondList
, thirdList
oder fourthList
erweitert richtig. Ich habe auch verschiedene Versionen von ausprobiert, eval
aber auch keine. Jede Hilfe wäre dankbar
#!/bin/bash
touch a.ext1
touch b.ext1
firstList='*.ext1'
ls $firstList
touch a.ext2
touch b.ext2
secondList='*.{ext1,ext2}'
ls $secondList
ls '$secondList'
ls "$secondList"
thirdList=*.{ext1,ext2}
ls $thirdList
ls '$thirdList'
ls "$thirdList"
fourthList="*.{ext1,ext2}"
ls $fourthList
ls '$fourthList'
ls "$fourthList"
bash
brace-expansion
Leo Simon
quelle
quelle
eval ls $secondList
funktioniert hier gut ... was versuchst du zu erreichen?eval
eine zweite Erweiterungsrunde durchführen.Antworten:
Die Shell wird
*
nur erweitert , wenn sie nicht in Anführungszeichen gesetzt ist. Bei Anführungszeichen wird die Erweiterung durch die Shell gestoppt.Außerdem muss eine Klammererweiterung nicht zitiert werden, um von der Shell erweitert zu werden.
Diese Arbeit (verwenden wir Echo, um zu sehen, was die Shell tut):
Auch wenn es Dateien mit anderen Namen gibt:
Warum funktioniert das?
Es ist wichtig, dass wir verstehen, warum das funktioniert. Es liegt an der Reihenfolge der Expansion. Zuerst die "Brace-Erweiterung" und später (die letzte) "Pathname-Erweiterung" (auch bekannt als Glob-Erweiterung).
Wir können "Pathname-Erweiterung" für einen Moment deaktivieren:
Die "Pfadnamenerweiterung" erhält zwei Argumente:
*.ext1
und*.ext2
.Das Problem ist, dass wir keine Variable für die Klammererweiterung verwenden können.
Es wurde schon oft erklärt , dass eine Variable in einer "Klammererweiterung" verwendet wird.
Um eine "Klammererweiterung" zu erweitern, die das Ergebnis einer "variablen Erweiterung" ist, müssen Sie die Befehlszeile erneut an die Shell mit senden
eval
.Werte der Dateinamen bringen kein Ausführungsproblem für eval:
Aber der Wert von
$list
könnte unsicher sein. Der Wert von$list
wird jedoch vom Skriptschreiber festgelegt. Der Skriptschreiber hat die Kontrolle übereval
: Verwenden Sie nur keine extern festgelegten Werte für$list
. Versuche dies:Eine bessere Alternative.
Eine Alternative (ohne Auswertung) ist die Verwendung von Bash "Extended Patterns" :
Hinweis: Bitte beachten Sie, dass beide Lösungen (Bewertung und Muster) (wie geschrieben) für Dateinamen mit Leerzeichen oder neuen Zeilen sicher sind. Wird aber für ein
$list
mit Leerzeichen fehlschlagen , weil$list
nicht zitiert oder die Auswertung die Anführungszeichen entfernt.quelle
Erwägen:
Das Problem ist , dass Klammer Expansion erfolgt , bevor variable Expansion . Das bedeutet, dass oben keine Klammererweiterung durchgeführt wird.
Dies liegt daran, dass beim ersten Aufrufen der Befehlszeile durch bash keine geschweiften Klammern vorhanden sind. Nach dem
secondList
Erweitern ist es zu spät.Folgendes wird funktionieren:
Hier verfügt die Befehlszeile über geschweifte Klammern, sodass die Klammererweiterung als erster Schritt ausgeführt werden kann. Danach wird der Wert von
$s
in ( variable Erweiterung ) eingesetzt, und zuletzt wird die Pfadnamenerweiterung durchgeführt.Dokumentation
man bash
erklärt die Reihenfolge der Erweiterung:quelle