Obter 'scp path /' se comportar como 'rsync path /'

1

Eu tenho estrutura de arquivos local:

/tmp/24
    /dir1
        /file1
        /file2
    /dir2
        /file3
        /file4

e eu quero enviá-lo para computação remota. Quando eu uso

rsync /tmp/24 host:/target

ele cria dentro do diretório target no host remoto ( /target/24/dir1/file1 , ...). Mas quando eu uso assim

rsync /tmp/24/ host:/target

faz o que eu quero e é para criá-los assim: /target/dir1/file1 . No entanto, scp faz a primeira coisa se a pasta de destino já existir e a segunda, quando não existe, independentemente do caminho terminar com / ou não. Como posso forçar o scp a se comportar como rsync no segundo exemplo?

    
por graywolf 28.06.2016 / 18:24

2 respostas

4

O trailing '/' no nome do diretório de origem é uma sutileza do rsync. Preste atenção nisso.

rsync

Uma barra à direita na fonte significa efetivamente "copiar o conteúdo deste diretório, não o próprio diretório". Sem a barra final, significa "copiar o diretório".

Portanto, rsync -a tmp/24/ host:/target copiará o conteúdo de "/ tmp / 24 /" para "host: / target /…".

Mas rsync -a tmp/24 host:/target copiará o diretório "/ tmp / 24 /" (e seu conteúdo) para "host: / target / 24 /…".

Não importa se "host: / target /" ainda não existe; ele será criado, se necessário, e os resultados serão os mesmos, de qualquer forma.

(Trailing barras no destino não importa.)

┌─────────────────────────┬───────────────┬───────────────────────┐
│ rsync                   │ target exists │ target does not exist │
├─────────────────────────┼───────────────┼───────────────────────┤
│ rsync -a tmp/24 target  │ target/24/…   │ target/24/…           │
├─────────────────────────┼───────────────┼───────────────────────┤
│ rsync -a tmp/24/ target │ target/…      │ target/…              │
└─────────────────────────┴───────────────┴───────────────────────┘

scp

As barras não são importantes, apenas se o diretório de destino existe ou não. Se existir, o diretório de origem será copiado para o diretório de destino, caso contrário, o diretório de destino será criado como um clone da origem.

┌───────────────────────┬───────────────┬───────────────────────┐
│ scp                   │ target exists │ target does not exist │
├───────────────────────┼───────────────┼───────────────────────┤
│ scp -r tmp/24 target  │ target/24/…   │ target/…              │
├───────────────────────┼───────────────┼───────────────────────┤
│ scp -r tmp/24/ target │ target/24/…   │ target/…              │
└───────────────────────┴───────────────┴───────────────────────┘

Então você está certo, você deve apenas fazer ssh host mkdir -p /target primeiro, e então o comportamento será o mesmo que para o rsync.

Mas por que não apenas usar o rsync? Ele faz muito mais, como transferências parciais, transferências interrompidas e dados compactados.

rsync -azu tmp/24 host:/target

cp

E para completude: no Mac, o rastreio '/' fornece a semântica rsync desde que o destino já exista.

┌──────────────────────┬───────────────┬───────────────────────┐
│ cp (Mac)             │ target exists │ target does not exist │
├──────────────────────┼───────────────┼───────────────────────┤
│ cp -a tmp/24 target  │ target/24/…   │ target/…              │
├──────────────────────┼───────────────┼───────────────────────┤
│ cp -a tmp/24/ target │ target/…      │ target/…              │
└──────────────────────┴───────────────┴───────────────────────┘

No Linux, as barras não importam, assim como o scp:

┌──────────────────────┬───────────────┬───────────────────────┐
│ cp (Linux)           │ target exists │ target does not exist │
├──────────────────────┼───────────────┼───────────────────────┤
│ cp -a tmp/24 target  │ target/24/…   │ target/…              │
├──────────────────────┼───────────────┼───────────────────────┤
│ cp -a tmp/24/ target │ target/24/…   │ target/…              │
└──────────────────────┴───────────────┴───────────────────────┘

idem

Adicionando em… ditto (1) é uma ferramenta do Mac OS para clonar um diretório. Faz uma cópia tão exata quanto possível.

As barras não são importantes. Se o diretório de destino já existe ou não, não importa.

┌──────────────────────┬──────────┐
│ ditto tmp/24 target  │ target/… │
└──────────────────────┴──────────┘

Se o destino já existir, os arquivos existentes anteriormente serão sobrescritos incondicionalmente. Os arquivos no destino que não estão na origem são deixados em paz.

    
por 29.06.2016 / 03:34
1

huh, então meu problema pode ser resolvido assim:

ssh host "mkdir -p /target"
scp tmp/24/* host:/target
    
por 29.06.2016 / 00:34