Ich versuche, mehrere Dateien aus einem Shellscript in ein Verzeichnis zu kopieren. Diese Dateien enthalten alle Arten von "hässlichen" Zeichen, wie Leerzeichen, Klammern und was sonst nicht. Allerdings stecke ich fest, wenn es darum geht, diesen als zu entkommen bash
und cp
scheinen sehr seltsam damit umzugehen.
Hier ist das Szenario:
Wenn ich diesen Befehl in meiner Shell absetze, funktioniert das wie ein Zauber:
cp /somedir/a\ file.png /somedir/another\ file.png /someotherdir/
Beim Lesen der zu kopierenden Dateien aus einem String wird es jedoch plötzlich seltsam:
var="/somedir/a\ file.png /somedir/another\ file.png"
cp "$ var" / someotherdir /
Ergebnisse in cp: cannot stat 'a\\ file.png another\\ file.png': No such file or directory
Ich glaube, das liegt daran, dass ich die Variable als String gebe und cp
glaubt, es ist eine Datei, obwohl es mehrere Dateien ist. Wenn Sie denselben Befehl ausführen, ohne die Variable in Anführungszeichen zu setzen ( var="/somedir/a\ file.png /somedir/another\ file.png"; cp $var /someotherdir/
) Ich bekomme einen noch seltsameren Fehler:
cp: cannot stat 'a\\ file.png another\\ file.png': No such file or directory
cp: cannot stat 'file.png': No such file or directory
cp: cannot stat 'another\\': No such file or directory
cp: cannot stat 'file.png': No such file or directory
Es scheint meine Flucht völlig zu ignorieren. Was mache ich falsch?
BEARBEITEN :// Wie es scheint Liste der Dateien kopieren hat eine Antwort mit xargs
, aber ich frage mich immer noch, warum bash sich hier so komisch verhält.
quelle
Wenn bash eine Befehlszeile analysiert, werden zuerst Anführungszeichen, Escapezeichen usw. interpretiert und anschließend Variablen ersetzt. Wenn die Variablenwerte Escapezeichen, Anführungszeichen usw. enthalten, werden sie nie wirksam, da es zu spät ist, bis sie in den Befehl aufgenommen werden, um den beabsichtigten Effekt zu erzielen.
Im Allgemeinen besteht die beste Möglichkeit zur Behebung dieses Problems darin, die Dateinamen in einem Array (ein Element pro Dateiname) und nicht in einer Zeichenfolgenvariablen zu speichern. dann benutze
"${array[@]}"
So erweitern Sie das Array, wobei jedes Element als separates "Wort" behandelt wird:Update: Wenn Sie die Dateiliste dynamisch erstellen müssen, ist das mit einem Array ganz einfach:
quelle
Wenn Sie bash verwenden, können Sie den Namen der Datei in doppelte Anführungszeichen setzen, um die Verwendung von Escapezeichen zu vermeiden:
Verwenden Sie dies stattdessen, wenn Sie verwenden
#!/bin/bash
In Ihrem Shell-Skript:In Ihrem Fall verwenden Sie die Werte in einer Variablen, aber Sie übergeben die Variable falsch. Wenn eine Variable Leerzeichen enthält, müssen Sie sie in Anführungszeichen setzen:
Wenn Sie es nicht in Anführungszeichen setzen, werden mehrere durch Leerzeichen getrennte Variablen verwendet.
quelle