Ich habe einen Suchbefehl, der bestimmte Dateien und Verzeichnisse findet. Dieser Suchbefehl führt dann rsync mit den zuvor gefundenen Dateien und Verzeichnissen als Quelle aus. Das Problem ist, dass diese Dateien und Verzeichnisse alle möglichen Zeichen wie einfache und doppelte Anführungszeichen enthalten können, ganz zu schweigen von illegalen Zeichen von Windows usw.
Wie kann ich einen String dynamisch maskieren, um ihn in rsync oder anderen Befehlen zu verwenden?
Dieser Befehl funktioniert, indem doppelte Anführungszeichen für die rsync-Quellzeichenfolge fest codiert werden, aber es bricht ab, wenn die Zeichenfolge doppelte Anführungszeichen enthält.
find "/mnt/downloads/cache/" -depth -mindepth 1 \( \
-type f \! -exec fuser -s '{}' \; -o \
-type d \! -empty \) \
\( -exec echo rsync -i -dIWRpEAXogt --numeric-ids --inplace --dry-run '"{}"' "${POOL}" \; \)
resultierende Ausgabe:
rsync -i -dIWRpEAXogt --numeric-ids --inplace --dry-run "test/this " is an issue" /mnt/backing
Arbeitsbefehl nach Info in Antworten angewendet:
find "/mnt/downloads/cache/" -depth -mindepth 1 \( \
-type f \! -exec fuser -s {} \; -o \
-type d \! -empty \) \
\( -exec rsync -i -dIWRpEAXogt --remove-source-files-- "${POOL} \; \) \
-o \( -type d -empty -exec rm -d {} \; \)
Akzeptierte Antwort:
Ihr Zitierproblem kommt daher, dass Sie versuchen, ein Problem zu lösen, das Sie gar nicht haben. Die Notwendigkeit, Argumente in Anführungszeichen zu setzen, kommt nur ins Spiel, wenn Sie es mit einer Shell zu tun haben und wenn find
ruft rsync
auf direkt, es ist keine Shell beteiligt. Die Verwendung einer visuellen Ausgabe ist keine gute Möglichkeit, um festzustellen, ob es funktioniert oder nicht, da Sie nicht sehen können, wo jedes Argument beginnt und endet.
Folgendes meine ich:
# touch "foo'\"bar"
# ls
foo'"bar
# find . -type f -exec stat {} \;
File: ‘./foo'"bar’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 1659137 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1004/ phemmer) Gid: ( 1004/ phemmer)
Access: 2017-12-09 13:21:28.742597483 -0500
Modify: 2017-12-09 13:21:28.742597483 -0500
Change: 2017-12-09 13:21:28.742597483 -0500
Birth: -
Beachten Sie, dass ich den {}
nicht zitiert habe im Argument zu stat
.
Nun, das heißt, Ihr Befehl wird sehr leistungsschwach sein, weil Sie rsync
aufrufen für jede einzelne passende Datei. Es gibt zwei Möglichkeiten, wie Sie dies lösen können.
Wie andere angedeutet haben, können Sie die Dateiliste an rsync
weiterleiten auf stdin:
# find . -type f -print0 | rsync --files-from=- -0 . dest/
# ls dest/
foo'"bar
Dies verwendet Null-Bytes als Dateinamen-Trennzeichen, da Dateien keine Null-Bytes in ihrem Namen enthalten dürfen.
Verwandte Themen:Wie behebt man den Fehler „Unbekanntes USB-Gerät benötigt mehr Strom, als der Anschluss liefern kann“?
Wenn Sie GNU find
verwenden , haben Sie eine andere Methode zum Aufrufen von -exec
, und das ist -exec {} +
. In diesem Stil find
wird mehr als ein Argument gleichzeitig übergeben. Alle Argumente werden jedoch am Ende des Befehls hinzugefügt, nicht in der Mitte. Sie können dies angehen, indem Sie die Argumente durch eine kleine Shell leiten:
# find . -type f -exec sh -c 'rsync "[email protected]" dest/' {} +
# ls dest/
foo'"bar
Dadurch wird die Liste der Dateien an sh
übergeben wodurch sie dann durch den "[email protected]"
ersetzt werden