Fish가 생성한 Rsync 명령에 예상치 못한 효과가 있습니다.

Fish가 생성한 Rsync 명령에 예상치 못한 효과가 있습니다.

저는 피쉬 셸을 사용하고 있으며 매개 변수가 모두 설정된 rsync 명령을 생성하는 도우미 함수가 있습니다. 최종 rsync 명령은 다음과 같아야 합니다(명령은 한 줄로 되어 있지만 읽기 쉽기 때문에 여러 줄로 만들었습니다).

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

터미널에서는 정상적으로 작동하지만 도우미 기능을 사용하려고 하면 "제외" 매개변수가 아무런 효과가 없는 것 같습니다. 생성된 명령은 ssh 명령이 따옴표로 묶여 있지 않다는 점을 제외하면 완전히 동일해 보입니다. 하지만 서버에 접속할 수 있기 때문에 문제가 되지는 않는 것 같습니다. 내가 말했듯이 유일한 문제는 제외 항목이 무시된다는 것입니다.

생성된 명령은 다음과 같습니다.

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

어떤 아이디어?

함수는 다음과 같습니다:

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

[편집하다]: Glenn의 답변 덕분에 함수에 따옴표 리터럴을 사용하면 문제가 발생한다는 것을 이해합니다. 그러나 공백으로 구분된 여러 값이 있는 인수를 arg1 arg2와 같이 분리하는 매우 편리한 효과가 있습니다 --exclude="arg1" --exclude="arg2". 불편함 없이 장점을 가질 수 있는 방법은 없을까요?

답변1

리터럴 따옴표 문자를 추가하고 있습니다.

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

그러면 rsync가 문자 그대로 파일 이름에 따옴표가 있는 파일을 찾게 됩니다.

단어를 묶을 때 따옴표를 사용하고 싶을 뿐입니다.

... "--exclude=$exclude"

따옴표의 목적은 명령을 토큰화하도록 쉘에 지시하는 것입니다.그것을 원한다. 실제 인용 문자는 쉘이 실제로 명령을 실행하기 전에 제거됩니다.


알겠습니다.목록$exclude의 항목 수입니다. 대신 중괄호를 사용하세요: 데모:

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

$exclude가 비어 있으면 매개변수에 다음이 포함됩니다.아니요--제외 옵션:

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

관련 정보