Stephen Rauch's Antwort beschreibt das Problem. Ich habe eine andere Lösung.
Aber zuerst: Warum setzen Sie einen so langen Befehl in eine Variable? Nur damit Sie es ausdrucken können? Warum nicht einfach die verbose-Option (Befehle anzeigen) der Shell verwenden?
set -v (dein_Befehl) set + v
Die x
Option (Ablaufverfolgung) ist ähnlich. Versuchen Sie es mit set -x
und set +x
, um den Unterschied zu sehen. Wenn Sie beide mögen, können Sie sie mit set -vx
und kombinieren set +vx
.
Es ist eine ziemlich schlechte Idee, eine Zeichenfolge aus einer Folge von Wörtern zu erstellen, die durch Leerzeichen getrennt sind, und dann zu versuchen, sie zu trennen, um die ursprünglichen Wortbestandteile wiederherzustellen. Sie haben eine der Fallen getroffen. Ein weiterer Grund ist die theoretische Möglichkeit, dass ein Dateiname Leerzeichen enthält. Es ist unmöglich, an der Befehlszeichenfolge zu erkennen, cat foo bar baz
dass foo bar
es sich um einen Dateinamen und einen baz
anderen handelt (und Sie haben gesehen, dass das Erstellen der Zeichenfolge ebenso cat "foo bar" baz
nicht gut funktioniert). Diese und andere Fragen werden hier diskutiert:
Sie müssen nicht printf
nur Strings verketten.
Wenn Sie Ihre Befehlszeile wirklich im Speicher erstellen möchten und bash verwenden, können Sie eine Array-Variable wie folgt verwenden:
DulicityCMD=(duplicity --log-file "$LOG_FILE" --progress --no-encryption --include="/etc" --include="/var/log" --include="/var/db" --include="/var/www" --include="/home" --exclude="**" / scp://duplicity@myhost.com:22//home/duplicity/backups/"$VPSNAME")
Beachten Sie, dass ich setzen $LOG_FILE
und $VPSNAME
in Anführungszeichen. Sie sollten immer alle Verweise auf Shell-Variablen angeben, es sei denn, Sie haben einen guten Grund, dies nicht zu tun, und wissen, was Sie tun. Aber Stephen hat Recht: Sie nicht wirklich brauchen, wie konstante Strings zitieren "/etc"
, "/var/log"
, "/var/db"
, und so weiter. (Aber natürlich, Sie tun müssen, zitieren "**"
, weil *
ein Sonderzeichen ist.)
Zur besseren Lesbarkeit können Sie die obigen Zeilen in mehrere Zeilen aufteilen. Beachten Sie, dass in der ersten Zeile =
und in den nachfolgenden Zeilen darauf hingewiesen wird +=
, dass sie das Vorherige hinzufügen:
DulicityCMD=(duplicity --log-file "$LOG_FILE" --progress --no-encryption) DulicityCMD+=(--include="/etc" --include="/var/log" --include="/var/db") DulicityCMD+=(--include="/var/www" --include="/home" --exclude="**") DulicityCMD+=(/ scp://duplicity@myhost.com:22//home/duplicity/backups/"$VPSNAME")
Dann kannst du es tun
printf "% s \ n" "$ " (um den Befehl zu drucken) "$ " (um den Befehl auszuführen)
oder verwenden Sie sudo "$"
, wenn Sie brauchen. Weitere Informationen zur Bash-Syntax finden Sie in bash (1). In meiner Antwort finden Sie weitere Informationen zu dieser Array-Technik.