Como faço para iterar a lista e copiar os arquivos de machineB e machineC eficientemente?

1

Eu preciso scp os arquivos de machineB e machineC para machineA . Estou executando meu script de shell abaixo de machineA . Eu configurei as chaves ssh corretamente.

Se os arquivos não estiverem em machineB , eles devem estar lá em machineC .

#!/bin/bash

readonly PRIMARY=/data01/primary/.
readonly FILERS_LOCATION=(machineB machineC)
readonly MAPPED_LOCATION=/bat/data/snapshot
PARTITION=(0 3 5 7 9)

dir1=20131222
dir2=20131222

scp david@${FILERS_LOCATION[0]}:$dir1/weekly_1980_[$el]_200003_5.data $PRIMARY || scp david@${FILERS_LOCATION[1]}:$dir2/weekly_1980_[$el]_200003_5.data $PRIMARY

Agora, minha pergunta é: se você der uma olhada no meu comando scp acima, eu tenho [$el] , preciso substituir isso por PARTITION , o que significa que preciso iterar PARTITION e substituir [$el] por cada número em PARTIÇÃO.

Então meu comando scp deve ficar assim se eu iterar PARTITION -

scp david@machineB:/bat/data/snapshot/20131222/weekly_1980_0_200003_5.data /data01/primary/. || scp david@machineC:/bat/data/snapshot/20131222/weekly_1980_0_200003_5.data /data01/primary/.

scp david@machineB:/bat/data/snapshot/20131222/weekly_1980_3_200003_5.data /data01/primary/. || scp david@machineC:/bat/data/snapshot/20131222/weekly_1980_3_200003_5.data /data01/primary/.

scp david@machineB:/bat/data/snapshot/20131222/weekly_1980_5_200003_5.data /data01/primary/. || scp david@machineC:/bat/data/snapshot/20131222/weekly_1980_5_200003_5.data /data01/primary/.

scp david@machineB:/bat/data/snapshot/20131222/weekly_1980_7_200003_5.data /data01/primary/. || scp david@machineC:/bat/data/snapshot/20131222/weekly_1980_7_200003_5.data /data01/primary/.

scp david@machineB:/bat/data/snapshot/20131222/weekly_1980_9_200003_5.data /data01/primary/. || scp david@machineC:/bat/data/snapshot/20131222/weekly_1980_9_200003_5.data /data01/primary/.
  1. Como faço para iterar PARTITION de tal forma que eu possa fazer a acima do comando SCP?
  2. E, como você pode ver, estou copiando os arquivos um por um na pasta machineA /data01/primary/ . Existe alguma maneira melhor de fazer isso? Ou seja, posso copiar todos os arquivos juntos em um único tiro, em vez de fazê-lo um por um?
por arsenal 24.12.2013 / 07:03

3 respostas

1

Para copiar todas as partições, use um curinga:

scp david@machineB:/bat/data/snapshot/20131222/weekly_1980_*_200003_5.data /data01/primary/. || scp david@machineC:/bat/data/snapshot/20131222/weekly_1980_*_200003_5.data /data01/primary/.

Se você copiar apenas as partições 0, 3, 5, 7, 9, use:

scp david@machineB:/bat/data/snapshot/20131222/weekly_1980_[03579]_200003_5.data /data01/primary/. || scp david@machineC:/bat/data/snapshot/20131222/weekly_1980_[03579]_200003_5.data /data01/primary/.

Se a lista de partições for especificada por uma variável, a mais simples seria:

PARTITION=03579
scp david@machineB:/bat/data/snapshot/20131222/weekly_1980_[$PARTITION]_200003_5.data /data01/primary/. || scp david@machineC:/bat/data/snapshot/20131222/weekly_1980_[$PARTITION]_200003_5.data /data01/primary/.

Se for especificado em uma matriz:

PARTITION=(0 3 5 7 9)
oldIFS="$IFS"
IFS=""
scp david@machineB:/bat/data/snapshot/20131222/weekly_1980_["${PARTITION[*]}"]_200003_5.data /data01/primary/. || scp david@machineC:/bat/data/snapshot/20131222/weekly_1980_["${PARTITION[*]}"]_200003_5.data /data01/primary/.
IFS="$oldIFS"
    
por 24.12.2013 / 07:40
1
#!/bin/bash

readonly PRIMARY=/data01/primary/.
readonly FILERS_LOCATION=(machineB machineC)
readonly MAPPED_LOCATION=/bat/data/snapshot

for i in 0 3 5 7 9
do
    scp david@${FILERS_LOCATION[0]}:$dir1/weekly_1980_${i}_200003_5.data PRIMARY || scp david@${FILERS_LOCATION[1]}:$dir2/weekly_1980_${i}_200003_5.data $PRIMARY
done
    
por 24.12.2013 / 07:59
1

Para copiar muitos arquivos de uma só vez, use rsync em vez de scp . O Rsync usa a conexão SSH para transferir arquivos remotamente.

rsync_filter=()
for el in "${PARTITION[@]}"; do
  rsync_filter+=(--include="weekly_1980_${el}_200003_5.data")
done
for machine in "${FILERS_LOCATION[@]}"; do
  rsync -a "${rsync_filter[@]}" --exclude='*' "david@$machine:$dir1/" "$PRIMARY/"
done

O Rsync irá ignorar a cópia se os arquivos já estiverem presentes com o mesmo tamanho e hora de modificação (você pode configurar isso).

Alternativamente, esqueça tudo sobre o fato de que eles são cópias remotas. Monte o sistema de arquivos remoto com SSHFS e prossiga como você copiaria os arquivos locais.

mkdir machineB machine C
sshfs david@machineB: machineB
sshfs david@machineC: machineC
for el in "${PARTITION[@]}"; do
  cp -p "machineB/$dir1/weekly_1980_${el}_200003_5.data" "$PRIMARY/" ||
  cp -p "machineC/$dir1/weekly_1980_${el}_200003_5.data" "$PRIMARY/"
done

Você pode até fazer um melhor e fazer uma montagem de união das duas máquinas. Uma montagem de união une duas árvores de diretório em uma, de tal forma que acessar um arquivo da árvore de união tenta dentro de uma árvore primeiro, e se o arquivo não estiver presente, tenta a mesma localização na outra árvore.

mkdir union
mount -t aufs -o dirs=$PWD/machineB:$PWD/machineC machineB+machineC union
for el in "${PARTITION[@]}"; do
  cp -p "union/$dir1/weekly_1980_${el}_200003_5.data" "$PRIMARY/"
done
    
por 25.12.2013 / 00:48