2017-12-28 4 views
2

Entschuldigen Sie den Wortlaut des Titels, ich bin mir nicht sicher, wie ich einen einprägsamen Titel für dieses "Problem" haben soll.Bash-Platzhalter (*) im Befehl bewirkt, dass die korrekte Ausgabe erfasst wird

Wenn ich den folgenden Befehl in meinem Terminal laufen (Laufen MacOS Sierra 10.12.6) git branch --list [rR]elease*

Es ergibt sich folgende erwartete Ergebnis

* Release-x 
    release-1 
    release-2 
    release-3 

jedoch Wenn ich folgendes in einem Bash setzen Skript

branches=($(git branch --list [rR]elease*)) 

for branch in "${branches[@]}" 
do 
    echo "Found branch $branch" 
done 

Es scheint die * zu nehmen und echo die Zweige gefunden und jeder fil e/Verzeichnisname in meinem aktuellen Arbeitsverzeichnis.

Found branch README.md 
Found branch acceptance-test 
Found branch build 
Found branch build.gradle 
Found branch flow.sh 
Found branch gradle 
Found branch gradle.properties 
Found branch gradlew 
Found branch gradlew.bat 
Found branch performance-tests 
Found branch postman 
Found branch service 
Found branch settings.gradle 
Found branch sonar-project.properties 
Found branch Release-x 
Found branch release-1 
Found branch release-2 
Found branch release-3 

Warum unterscheiden sich die Ausgänge? Derzeit bricht dies die Logik des Skripts, da es Verzweigungen erwartet. Ich möchte vermeiden, redundante Prüfungen (überprüfen Sie, ob dies eine tatsächliche Zweigstelle ist) das Skript überfluten, wenn möglich.

Edit: Ich habe versucht, die * zitiert und es produziert das gleiche Ergebnis wie oben.

Visual version of the problem

Antwort

1

$(git...) erfährt Expansion Pfadname, bevor er im Array gespeichert ist. * branchname markiert den aktuellen Zweig in git. Das * in der Ausgabe des Befehls git erweitert sich auf alle Dateien in Ihrem aktuellen Verzeichnis, wenn das Array branches erstellt wird.

Sie können die Pfadnamenerweiterung mit set -f deaktivieren. Außerdem müssen Sie festlegen $IFS nur ein <newline>, sonst Linien mit einem Leerzeichen würde in mehrere Elemente aufgeteilt bekommen (*<space>branchname würde * und branchname werden):

old_IFS=$IFS 
IFS=$'\n' 
set -f 
branches=($(git branch --list '[rR]elease*'))  
set +f 
IFS=$old_IFS 

Oder der bessere Weg ist readarray zu verwenden:

readarray -t branches < <(git branch --list '[rR]elease*') 

Oder Sie können eine while Schleife mit read verwenden. Dies wird auch die führenden Räume beschneiden. Wenn das nicht gewünscht ist, verwenden Sie IFS= read -r ...:

branches=() 
while read -r branch; do 
    branches+=("$branch") 
done < <(git branch --list '[rR]elease*') 
Verwandte Themen