
Ich habe wirklich Probleme damit, eine Befehlsargumentvariable mit rsync zum Laufen zu bringen. Das Verhalten, das ich sehe, ist dieser Fehler aus dem Skript:
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(601) [sender=3.0.7]
Das Skript gibt den auszuführenden Befehl jedoch über ein Echo aus, und wenn man den exakt gleichen Befehl in das Terminal kopiert und einfügt (oder als erste Zeile mit einem „Exit“ dahinter zurück in das Skript), funktioniert das einwandfrei?!
Skriptcode, der dieses rsync ausführt (check_flags ist in diesem Fall leer):
rsync_cmd=(${check_flags} -rWltpgoDvdHP --delete-before -- \"${backup_dir}\" \"admin@nas-1:${backup_basename}/\")
echo "CMD to run: rsync ${rsync_cmd[@]}"
rsync ${rsync_cmd[@]}
Ausgabe:
CMD to run: rsync -rWltpgoDvdHP --delete-before -- "/share/CACHEDEV1_DATA/veeam_backup_daily/Daily backup _@1am__1" "admin@nas-1:/share/CACHEDEV1_DATA/veeam_backup_daily/"
Ich habe online gelesen, dass die Verwendung eines Arrays dieses Problem lösen soll, aber in diesem Fall hat es nicht geholfen. Ich bin ziemlich sicher, dass das leicht zu beheben ist, aber es macht mich wahnsinnig!
Antwort1
Die Shell analysiert Anführungszeichen, bevor sie Variablen ersetzt. Daher bewirkt das Einfügen von Anführungszeichen in den Variablenwert nicht das Erwartete (und das echo
ist höchst irreführend, da es diesen Unterschied nicht zeigt). Was Sie tun sollten, ist, beim Definieren des Arrays Anführungszeichen ohne Escapezeichen zu verwenden (damit sie als Trennzeichen um Array-Elemente analysiert werden und nicht als Teil des Array-Werts) und dann den Verweis auf das Array in doppelte Anführungszeichen zu setzen (damit die Werte im Array nicht durch Wörter getrennt oder mit Platzhaltern erweitert werden). Ich würde den echo
Befehl auch durch ein ersetzen printf
, das genauer zeigt, was passieren wird:
rsync_cmd=(${check_flags} -rWltpgoDvdHP --delete-before -- "${backup_dir}" "admin@nas-1:${backup_basename}/")
printf "%q " CMD to run: rsync "${rsync_cmd[@]}"
printf "\n"
rsync "${rsync_cmd[@]}"
Beachten Sie, dass printf
möglicherweise nicht das angezeigt wird, was Sie erwarten - es wird einÄquivalentDarstellung des auszuführenden Befehls, aber es gibt viele verschiedene äquivalente Darstellungen jedes Arguments, und es wird eine basierend auf seinen Präferenzen ausgewählt, nicht basierend auf der ursprünglichen Eingabe. Übrigens können Sie auch verwenden, set -x
um solche Dinge zu debuggen, aber (wie bei printf "%q "
) kann es eine andere Darstellung verwenden, als Sie erwarten.