$@에서 여러 제외를 전달하는 rsync

$@에서 여러 제외를 전달하는 rsync

코드를 재사용하기 위해 rsync 명령 주위에 래퍼를 만들려고 합니다. 소스 폴더, 대상 폴더, 그리고 제외된 디렉터리 수를 전달해야 합니다. 내 로그는 다음과 같습니다. 기본적으로 "vararg" 매개변수에서 매개변수를 제외하고 여러 rsync를 작성하고 있습니다. 더 좋은 방법이 있을 수 있지만 저는 그 방법으로 충분하다고 생각합니다.

function run_backup(){
    source="$1"
    target="/backups/unraid$2"
    #Copying $source into remote folder $target

    # Building my exclude params
    if [ $# -ge 3 ]; then
        excludes="--exclude '$3'"
        while shift && [ -n "$3" ]; do
            echo $excludes
            excludes="${excludes} --exclude '$3'"
        done
    else
        excludes = "--exclude '/tmp'" # Dummy exclude; I'll handle this case later
    fi
    echo $excludes
    
    # Creating folder because rsync crash otherwise n some case
    ssh -p 22 -i /home/backup/.ssh/mykey [email protected] "mkdir -p $target"

    # Executing the copy
    set -e
    sudo rsync -azvh \
        -e "ssh  -p 22-i /home/backup/.ssh/mykey "\
        --progress \
        --delete \
        $excludes \
        $source \
        [email protected]:$target
}


mkdir -p /tmp/dummy
echo "dummy" > /tmp/dummy/save-ignored-1
echo "dummy" > /tmp/dummy/save-ignored-2
echo "dummy" > /tmp/dummy/save-test
run_backup /tmp/dummy/ /dummy /tmp/dummy/save-ignored-1 /tmp/dummy/save-ignored-2 /tmp/toto /tmp/tata /tmp/tutu #TODO
--exclude '/tmp/dummy/save-ignored-1'
--exclude '/tmp/dummy/save-ignored-1' --exclude '/tmp/dummy/save-ignored-2'
--exclude '/tmp/dummy/save-ignored-1' --exclude '/tmp/dummy/save-ignored-2' --exclude '/tmp/toto'
--exclude '/tmp/dummy/save-ignored-1' --exclude '/tmp/dummy/save-ignored-2' --exclude '/tmp/toto' --exclude '/tmp/tata'
--exclude '/tmp/dummy/save-ignored-1' --exclude '/tmp/dummy/save-ignored-2' --exclude '/tmp/toto' --exclude '/tmp/tata' --exclude '/tmp/tutu'
++ ssh -p 22-i /home/backup/.ssh/mykey [email protected] 'mkdir -p /backups/unraid/dummy'
++ sudo rsync -azvh -e 'ssh  -p 22 -i /home/backup/.ssh/mykey' --progress --delete --exclude ''\''/tmp/dummy/save-ignored-1'\''' --exclude ''\''/tmp/dummy/save-ignored-2'\''' --exclude ''\''/tmp/toto'\''' --exclude ''\''/tmp/tata'\''' --exclude ''\''/tmp/tutu'\''' /tmp/dummy/ [email protected]:/backups/unraid/dummy

var가 정확히 내가 원하는 것임을 알 수 있지만 $excludes이를 rsync에 전달하면 bash가 이에 대해 마법을 수행합니다. 나는 이것을 피하는 방법을 모른다. 확장 기능과 관련이 있는 것 같은데 내 문서나 관련 문서와 비슷한 질문을 찾을 수 없습니다.

편집: 첫 번째 답변 이후의 코드:

function run_backup(){
    excludes=()
    if [ $# -ge 3 ]; then
        echo $3
        excludes+=(--exclude $3)
        while shift && [ -n "$3" ]; do
            echo $3
            excludes+=(--exclude $3)
        done
    else
        excludes+=(--exclude /tmp)
    fi
    set -x
    echo "${excludes[@]}"
}
run_backup /tmp/dummy/ /dummy "/tmp/dummy/save-ignored" "/tmp/dummy/save non'standard ignored" /tmp/toto /tmp/tata /tmp/tutu

하지만 따옴표(적어도 간단한 따옴표)가 포함된 문자열에서는 작동하지 않습니다.

/tmp/dummy/save-ignored
/tmp/dummy/save non'standard ignored
/tmp/toto
/tmp/tata
/tmp/tutu
++ echo --exclude /tmp/dummy/save-ignored --exclude /tmp/dummy/save 'non'\''standard' ignored --exclude /tmp/toto --exclude /tmp/tata --exclude /tmp/tutu
--exclude /tmp/dummy/save-ignored --exclude /tmp/dummy/save non'standard ignored --exclude /tmp/toto --exclude /tmp/tata --exclude /tmp/tutu

편집 2:쓸모가 없습니다. 그냥 기록으로 유지하세요. 모든 제안 가능성을 테스트해 보세요.

run_backup(){
    excludes=()
    excludes2=()
    excludes3=()
    if [ $# -ge 3 ]; then
        echo $3
        excludes+=(--exclude $3)
        excludes2+=(--exclude "$3")
        excludes3+=(--exclude "\"$3\"")
        while shift && [ -n "$3" ]; do
            echo $3
            excludes+=(--exclude $3)
            excludes2+=(--exclude "$3")
            excludes3+=(--exclude "\"$3\"")
        done
    else
        excludes+=(--exclude /tmp)
    fi
    set -x
    echo "${excludes[@]}"
    echo "${excludes2[@]}"
    echo "${excludes3[@]}"
     sudo rsync -azvh \
        --dry-run \
        "${excludes[@]}" \
        --dry-run \
        "${excludes2[@]}" \
        --dry-run \
        "${excludes3[@]}" \
        --dry-run \
        ${excludes[@]} \
        --dry-run \
        ${excludes2[@]} \
        --dry-run \
        ${excludes3[@]} \
        /tmp \
        [email protected]:/tmp
}
run_backup "/tmp/dummy/" "/dummy" "/tmp/dummy/save non'standard" "/tmp/toto"
++ echo --exclude /tmp/dummy/save 'non'\''standard' --exclude /tmp/toto
--exclude /tmp/dummy/save non'standard --exclude /tmp/toto
++ echo --exclude '/tmp/dummy/save non'\''standard' --exclude /tmp/toto
--exclude /tmp/dummy/save non'standard --exclude /tmp/toto
++ echo --exclude '"/tmp/dummy/save non'\''standard"' --exclude '"/tmp/toto"'
--exclude "/tmp/dummy/save non'standard" --exclude "/tmp/toto"
++ sudo rsync -azvh --dry-run --exclude /tmp/dummy/save 'non'\''standard' --exclude /tmp/toto --dry-run --exclude '/tmp/dummy/save non'\''standard' --exclude /tmp/toto --dry-run --exclude '"/tmp/dummy/save non'\''standard"' --exclude '"/tmp/toto"' --dry-run --exclude /tmp/dummy/save 'non'\''standard' --exclude /tmp/toto --dry-run --exclude /tmp/dummy/save 'non'\''standard' --exclude /tmp/toto --dry-run --exclude '"/tmp/dummy/save' 'non'\''standard"' --exclude '"/tmp/toto"' /tmp [email protected]:/tmp

더 나은 형식의 출력이 포함된 테스트 스크린샷:더 나은 형식의 출력이 포함된 테스트 스크린샷

답변1

문자열 대신 배열을 사용하세요.

예를 들어:

opt=()
opt+=(--exclude "first")
opt+=(--exclude "another one")

set -x
echo "${opt[@]}"

그러면 공백이 올바르게 처리됩니다(출력).

+ echo --exclude first --exclude 'another one'

관련 정보