Ajude o script Shell a passar variáveis para rsync

5

Estou tentando criar um script de shell simples para o rsync. Quando eu envio nomes de arquivos para o meu script, o rsync nunca parece identificar o local correto. Os nomes dos arquivos possuem espaços. Eu tentei uma dúzia de diferentes variações usando aspas, aspas duplas, aspas invertidas e usando o sinalizador rsync -s --protect-args. Eu finalmente estou sem ideias. Aqui está uma versão simplificada do meu script.

#!/bin/bash
# Example usage:
#    pull.sh "file 1" "file 2"

LOCATION="/media/WD100"
all_files=""
for file in "$@"; do
        all_files="$all_files:\"$LOCATION/$file\" "
done
# Pull the given files from homeserver to my current directory.
rsync --progress --inplace --append-verify -ave ssh username@homeserver"$all_files" .

Eu deveria estar escrevendo isso de forma diferente? Como esse script funciona?

ATUALIZAÇÃO:

Eu mudei meu roteiro para tentar refletir a resposta de Chazelas, mas ainda parece não funcionar. Aqui está o meu novo código:

#!/bin/bash
# Example usage:
#    pull.sh "file 1" "file 2"

LOCATION="/media/WD100"
all_files=""
for file in "$@"; do
    all_files="$all_files\"$LOCATION/$file\" "
done
rsync --progress --inplace --append-verify -0 --files-from=<(printf '%s
rsync error: syntax or usage error (code 1) at options.c(1657) [server=3.0.9]
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: error in rsync protocol data stream (code 12) at io.c(605) [Receiver=3.0.9]
' "$all_files") -ave ssh username@homeserver: .

A execução me dá a saída padrão de "uso", com esse erro no final.

#!/bin/bash
# Example usage:
#    pull.sh "file 1" "file 2"

LOCATION="/media/WD100"
all_files=""
for file in "$@"; do
        all_files="$all_files:\"$LOCATION/$file\" "
done
# Pull the given files from homeserver to my current directory.
rsync --progress --inplace --append-verify -ave ssh username@homeserver"$all_files" .
    
por Sepero 17.01.2014 / 07:54

3 respostas

1

O problema é que você precisa citar os nomes dos arquivos, mas você não pode fazer tudo isso usando strings porque ele passará todos os nomes de arquivos para rsync como uma string longa com aspas dentro da string (e não o arquivo individual parâmetros de string).

A variável $ @ é um array no Bash. Você precisa convertê-lo em uma nova matriz ao enviar para o rsync.

LOCATION="/media/WD100/"
all_files=()
for file in "$@"; do
    all_files+=(":\"$LOCATION$file\"")
done
rsync --progress --inplace --append-verify -ave ssh username@homeserver"${all_files[@]}" .
    
por 18.01.2014 / 21:10
5

Uso:

# prepend "$location" to each element of the '"$@"' array:
for file do
  set -- "$@" "$location/$file"
  shift
done

rsync ... -0 --files-from=<(printf '%s
rsync ... -0 --files-from=<(
  for file do
    printf '%s
# prepend "$location" to each element of the '"$@"' array:
for file do
  set -- "$@" "$location/$file"
  shift
done

rsync ... -0 --files-from=<(printf '%s
rsync ... -0 --files-from=<(
  for file do
    printf '%s%pre%' "$location/$file"
  done) user@host: .
' "$@") user@host: .
' "$location/$file" done) user@host: .
' "$@") user@host: .

Ou:

%pre%

para estar no lado seguro.

Isso passa a lista de arquivos como uma lista delimitada pelo NUL por meio de um pipe nomeado para rsync .

    
por 17.01.2014 / 09:14
0

Como você está copiando todo o conteúdo do WD100 para o local atual, apenas deixe o rsync sincronizar o conteúdo do diretório.

rsync --progress --inplace --append-verify -ave ssh username@homeserver:/media/WD100/ ./

O rsync se comporta de maneira diferente dependendo da barra no final do caminho. Se não houver nenhuma barra, copia o objeto de diretório recursivamente, mas se houver uma barra, copiará o conteúdo do diretório recursivamente.

Aqui está a seção do manual do rsync que é pertinente.

A trailing slash on the source changes this behavior to avoid creating an additional directory level at the destination. You can think of a trailing / on a source as meaning lqcopy the contents of this directoryrq as opposed to lqcopy the directory by namerq, but in both cases the attributes of the containing directory are transferred to the containing directory on the destination. In other words, each of the following commands copies the files in the same way, including their setting of the attributes of /dest/foo:

rsync -av /src/foo /dest
rsync -av /src/foo/ /dest/foo
    
por 18.01.2014 / 22:36