Wenn ich benutze
cp -R inputFolder outputFolder
Das Ergebnis ist kontextabhängig :
- Ist
outputFolder
dies nicht der Fall, wird es erstellt und der Pfad des geklonten Ordners wird angezeigtoutputFolder
. - Wenn
outputFolder
vorhanden, wird der erstellte Klon erstelltoutputFolder/inputFolder
Das ist schrecklich , weil ich ein Installationsskript erstellen möchte, und wenn der Benutzer es versehentlich zweimal ausführt, hat er es outputFolder
beim ersten Mal erstellt, und beim zweiten Mal wird das gesamte Material in neu erstellt outputFolder/inputFolder
.
- Ich möchte immer das erste Verhalten: einen Klon neben dem Original erstellen (als Geschwister).
- Ich möchte
cp
portabel sein (zB MINGW wird nichtrsync
ausgeliefert) - Ich habe es überprüft,
cp -R --parents
aber dies stellt den Pfad bis zum Ende des Verzeichnisbaums wieder her (der Klon wird also nichtoutputFolder
aber seinsome/path/outputFolder
). --remove-destination
oder--update
falls 2 nichts ändert, werden noch dinge in kopiertoutputFolder/inputFolder
Gibt es eine Möglichkeit, dies zu tun, ohne vorher zu prüfen, outputFolder
ob der Ordner existiert (wenn er nicht existiert, dann ...) oder zu verwenden rm -rf outputFolder
?
Wie sieht die vereinbarte, portable UNIX-Methode dafür aus?
mv
eine Sammlung von Dateien in eine einzige reguläre verschoben wird?rsync
?cp
ist die Weiterleitung zwischen zweitar
Befehlen eine gute und zuverlässige Methode zum Kopieren von Bäumen.rsync
ausgeliefert wurde.tar -C input -cf - . | tar -C output -xf -
.-C
Ändert das Arbeitsverzeichnis, ist aber keine Standardoption. Wenn dies nicht unterstützt wird, müssen Sie zunächst die beiden Teer in den richtigen Arbeitsverzeichnissen ausführen. Beispiel:( cd input && tar -cf - . ) | ( cd output && tar -xf - )
Wenn Sie jedoch mit Windows arbeiten, würde ich nur die Antwort von Roaima verwenden.Antworten:
Verwenden Sie dies stattdessen:
Dies funktioniert genauso wie zum Beispiel
cp -R aaa/bbb ccc
: Wennccc
es keine gibt, wird sie als Kopie vonbbb
und ihrem Inhalt erstellt. Ist dies jedochccc
bereits der Fall,ccc/bbb
wird eine Kopie vonbbb
und deren Inhalt erstellt.Für fast jeden Fall
bbb
ergibt sich das unerwünschte Verhalten, das Sie in Ihrer Frage notiert haben. In dieser konkreten Situation ist dasbbb
jedoch gerecht.
, so wieaaa/bbb
es wirklich istaaa/.
, was wiederum wirklich gerecht ist,aaa
aber unter einem anderen Namen. Wir haben also diese beiden Szenarien:ccc
ist nicht vorhanden:Der Befehl
cp -R aaa/. ccc
bedeutet "ccc
den Inhalt vonaaa/.
in erstellen und kopierenccc/.
, dh kopierenaaa
inccc
.ccc
existiert:Der Befehl
cp -R aaa/. ccc
bedeutet "kopiere den Inhalt vonaaa/.
inccc/.
, dh kopiereaaa
inccc
.quelle
inputFolder/.
stattinputFolder
und in der Tat funktioniert es für mich auf Windows / Git Bash. (Es geht aber nicht mit nur einem abschließenden/
, ich brauche auch den Punkt nach dem Schrägstrich). Ich habe +1 gegeben, da es interessant ist, obwohl es wahrscheinlich ein bisschen zu schwierig ist, es in öffentlichem Code zu verwenden :)Kopieren Sie nicht den Ordner, sondern nur den Inhalt:
Auf diese Weise stellen Sie beide sicher, dass das Zielverzeichnis beim ersten Ausführen des Skripts erstellt wird, und vermeiden das Problem, wenn Sie es ein zweites Mal ausführen.
Chris Down weist sehr richtig darauf hin, dass in bash Dateien übersprungen werden, deren Name mit a beginnt
.
. Um dies zu vermeiden, können Sie ausführen,shopt -s dotglob
bevor Sie den obigen Befehl ausführen .Sowohl
-p
fürmkdir
als auch-R
fürcp
werden von POSIX definiert, daher sollte dies perfekt portierbar sein.quelle
.
. In Bash können Sie dafür verwendendotglob
.Versuchen Sie die
-T
Option zucp
. Dies existiert in GNU Coreutilscp
Version 8.22; es kann außerhalb davon nicht tragbar sein.quelle
cp -T
(cp --no-target-directory
). unix.stackexchange.com/questions/94831/… Leider ist meine Version voncp
viel älter.-u
ist eine großartige Option, um es faul zu machen.Sie könnten auch verwenden
rsync
:(Beachten Sie die Schrägstriche, besonders nach dem ersten)
quelle
Meiner Meinung nach gibt es nichts Einfacheres und Tragbareres als
rm -rf outputFolder
. Also bleibe ich immer dabei. Ich verstehe, dass Ihre Frage anders ist, aber ich denke, dass dies die beste Vorgehensweise ist.quelle
cp
gleich ist, sowohl wenn das Verzeichnis nicht existiert als auch wenn es existiert. Also, wovon redest du?cp
vom OP gegebene Befehl behält keine Berechtigungen (oder Zeitstempel) bei.Sie können die
-t
Befehlsoption verwendencp
als:Wenn der Zielordner nicht existiert, wird ein Fehler ausgegeben:
Der obige Befehl kopiert
inputFolder
zusammen mit dem Inhalt (und nicht nur mit dem Inhalt darin).Wenn Sie nur den Inhalt kopieren möchten, wird
inputFolder
es etwas knifflig (da Sie vorsichtig sein müssen, wenn Sie Shell-Globbing verwenden, während Sie Sternchen * verwenden).Wenn der Zielordner nicht existiert, wird ein Fehler ausgegeben:
arbeitet mit
cp (GNU coreutils) 8.23
quelle