Der von Fish generierte Rsync-Befehl hat unerwartete Auswirkungen

Der von Fish generierte Rsync-Befehl hat unerwartete Auswirkungen

Ich verwende die Fish-Shell und habe eine Hilfsfunktion, um einen Rsync-Befehl mit allen festgelegten Parametern zu generieren. Der endgültige Rsync-Befehl sollte wie folgt aussehen (der Befehl steht in einer Zeile, ich habe ihn mehrzeilig gemacht, weil er leichter zu lesen ist):

rsync -razs -e="ssh -p2222" --update --progress \ 
    --exclude=".*" --exclude="__pycache__" 
    --delete --dry-run \
    $source_dir $dest_dir

Vom Terminal aus funktioniert es einwandfrei, aber wenn ich versuche, meine Hilfsfunktion zu verwenden, scheinen die „Ausschluss“-Parameter keine Wirkung zu haben. Der generierte Befehl sieht genau gleich aus, außer dass der SSH-Befehl nicht in Anführungszeichen eingeschlossen ist. Dies scheint jedoch kein Problem zu sein, da ich eine Verbindung zum Server herstellen kann. Wie gesagt, das einzige Problem ist, dass die Ausschlüsse ignoriert werden.

Der generierte Befehl sieht folgendermaßen aus:

rsync -razs -e=ssh -p2222 --update --progress \
    --exclude=".*" --exclude="__pycache__" \
    --delete --dry-run \
    /home/some_folder user@host:/home/

Irgendeine Idee?

Die Funktion sieht folgendermaßen aus:

function ssync -d "rsync through ssh tunnel" 

    set origin $argv[1]
    set destination $argv[2]
    set exclude ".*" "__pycache__"

    set ssh_config "ssh -p2222"
    set params -razs -e="$ssh_config" --update --progress --exclude=\"$exclude\"

    if test (count $argv) -gt 2
        set option $argv[3]
        set params $params --delete
        if [ $option = "--delete" ]
            set_color red; echo "Warning: Unsafe run!";
            read -l -P "Confirm? [y/N] " yesno;
            switch $yesno
                case '' N n
                    echo "Sync canceled by user"
                    return 0
                case Y y
                    echo "Proceeding..."
            end
        else
            set params $params --dry-run
        end
    end

    echo "rsync $params $origin $destination"
    rsync $params $origin $destination;
end

[BEARBEITEN]: Dank Glenns Antwort verstehe ich, dass die Verwendung von Anführungszeichen in der Funktion das Problem verursacht. Es hat jedoch den sehr praktischen Effekt, ein Argument mit mehreren durch Leerzeichen getrennten Werten wie arg1 arg2in etwas wie zu trennen --exclude="arg1" --exclude="arg2". Gibt es eine Möglichkeit, die Vorteile ohne die Unannehmlichkeiten zu haben?

Antwort1

Sie fügen wörtliche Anführungszeichen hinzu

... --exclude=\"$exclude\"

Dadurch sucht rsync nach Dateien, deren Dateinamen Anführungszeichen enthalten.

Sie möchten lediglich Anführungszeichen verwenden, um das Wort

... "--exclude=$exclude"

Denken Sie daran, dass der Zweck der Anführungszeichen darin besteht, die Shell anzuweisen, den Befehl so zu tokenisieren,Dumöchten. Die eigentlichen Anführungszeichen werden entfernt, bevor die Shell den Befehl tatsächlich ausführt.


OK, Sie haben eineListevon Elementen in $exclude. Verwenden Sie stattdessen Klammern: demo:

$ set exclude ".*" file1 file2
$ set params --some stuff --other stuff --exclude={$exclude}
$ echo $params
--some stuff --other stuff --exclude=.* --exclude=file1 --exclude=file2

Beachten Sie, dass wenn $exclude leer ist, die Parameter enthaltenNEIN--exclude-Optionen:

$ set -e exclude
$ set params --some stuff --other stuff --exclude={$exclude}
$ echo $params
--some stuff --other stuff

verwandte Informationen