Как скопировать три файла одновременно, а не один файл за один раз в сценарии оболочки bash?

Я запускаю свой сценарий оболочки на machineA который копирует файлы из machineB и machineB .

Если файла нет в machineB , то он должен быть там в machineC . Поэтому я сначала попытаюсь скопировать файл с machineB , если его нет в machineB тогда я machineB к machineC чтобы скопировать те же файлы.

В machineB и machineB в этой папке будет такая папка, как этот YYYYMMDD

 /data/pe_t1_snapshot 

Итак, какая бы дата не была последней датой в этом формате YYYYMMDD внутри указанной папки – я выберу эту папку в качестве полного пути, откуда мне нужно начать копирование файлов –

так что предположим, что если это последняя папка даты 20140317 внутри /data/pe_t1_snapshot тогда это будет полный путь для меня –

 /data/pe_t1_snapshot/20140317 

откуда мне нужно начать копирование файлов в machineB и machineB . Мне нужно скопировать около 400 файлов в machineB из machineB и machineB и каждый размер файла составляет 2.5 GB .

Раньше я пытался копировать файлы один за другим в machineA который очень медленный. Есть ли способ, я могу скопировать «три» файла сразу в machineA используя потоки в сценарии оболочки bash?

Ниже приведен сценарий оболочки, который копирует файл один за другим в machineB из machineB и machineB .

 #!/usr/bin/env bash readonly PRIMARY=/export/home/david/dist/primary readonly FILERS_LOCATION=(machineB machineC) readonly MEMORY_MAPPED_LOCATION=/data/pe_t1_snapshot PRIMARY_PARTITION=(0 548 272 4 544 276 8 556 280 12 552 284 16 256 564 20 260 560 24 264 572) # this will have more file numbers around 200 dir1=$(ssh -o "StrictHostKeyChecking no" david@${FILERS_LOCATION[0]} ls -dt1 "$MEMORY_MAPPED_LOCATION"/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | head -n1) dir2=$(ssh -o "StrictHostKeyChecking no" david@${FILERS_LOCATION[1]} ls -dt1 "$MEMORY_MAPPED_LOCATION"/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | head -n1) ## Build your list of filenames before the loop. for n in "${PRIMARY_PARTITION[@]}" do primary_files="$primary_files :$dir1"/t1_weekly_1680_"$n"_200003_5.data done if [ "$dir1" = "$dir2" ] then find "$PRIMARY" -mindepth 1 -delete rsync -avz david@${FILERS_LOCATION[0]}"${primary_files}" $PRIMARY/ 2>/dev/null rsync -avz david@${FILERS_LOCATION[1]}"${primary_files}" $PRIMARY/ 2>/dev/null fi 

Поэтому я думаю вместо копирования одного файла за раз, почему бы просто не просто скопировать «три» файла сразу, и как только эти три файла будут выполнены, я перейду к другим трем файлам в списке, чтобы скопировать в одно и то же время?

Я попытался открыть три экземпляра шпатлевки и одновременно копировал один файл из этих трех экземпляров. Все три файла были скопированы через ~ 50 секунд, так что это было быстро для меня. По этой причине я пытаюсь скопировать сразу три файла вместо одного файла за раз.

Возможно ли это сделать? Если да, то может ли кто-нибудь представить пример по этому поводу? Я просто хотел сделать снимок и посмотреть, как это работает.

@terdon помог мне с вышеупомянутым решением, но я хотел попробовать сразу скопировать три файла, чтобы посмотреть, как он будет себя вести.

Обновить:-

Ниже приведен упрощенный вариант сценария оболочки. Он попытается скопировать файлы из machineB и machineB в machineA поскольку я запускаю сценарий ниже оболочки на machineA . Он попытается скопировать номера файлов, которые присутствуют в PRIMARY_PARTITION .

 #!/usr/bin/env bash readonly PRIMARY=/export/home/david/dist/primary readonly FILERS_LOCATION=(machineB machineC) readonly MEMORY_MAPPED_LOCATION=/data/pe_t1_snapshot PRIMARY_PARTITION=(0 548 272 4 544 276 8 556 280 12 552 284 16 256 564 20 260 560 24 264 572) # this will have more file numbers around 200 dir1=/data/pe_t1_snapshot/20140414 dir2=/data/pe_t1_snapshot/20140414 ## Build your list of filenames before the loop. for n in "${PRIMARY_PARTITION[@]}" do primary_files="$primary_files :$dir1"/t1_weekly_1680_"$n"_200003_5.data done if [ "$dir1" = "$dir2" ] then # delete the files first and then copy it. find "$PRIMARY" -mindepth 1 -delete rsync -avz david@${FILERS_LOCATION[0]}"${primary_files}" $PRIMARY/ rsync -avz david@${FILERS_LOCATION[1]}"${primary_files}" $PRIMARY/ fi 

Параллельно редко используется несколько копий: ограниченный ли коэффициент пропускной способности сети или пропускная способность диска, вы получите N параллельных потоков, каждый из которых будет в 1 / N раз быстрее.

С другой стороны, когда вы копируете или из нескольких источников (здесь B и C), тогда есть преимущество в том, чтобы делать копии параллельно, если узкое место находится на стороне B и C (а не на общая сторона). Поэтому вы можете попробовать сделать копии параллельно:

 rsync -avz david@${FILERS_LOCATION[0]}"${primary_files}" $PRIMARY/ & rsync -avz david@${FILERS_LOCATION[1]}"${primary_files}" $PRIMARY/ & wait 

Обратите внимание, что выходные данные из двух команд rsync будут перемешаны; вы можете отправить его в отдельные файлы.

 log_base=$(date +%Y%m%d-%H%M%S-$$) rsync -avz david@${FILERS_LOCATION[0]}"${primary_files}" $PRIMARY/ >$log_base-B.log & rsync -avz david@${FILERS_LOCATION[1]}"${primary_files}" $PRIMARY/ >$log_base-C.log & wait 

Вы используете несколько SSH-соединений для одного и того же адресата в своем скрипте. Установление соединения SSH имеет неизбежную задержку. Вы можете сэкономить немного времени, оставив соединение открытым и повторно используя его, что легко благодаря мастер-соединениям .

Вы можете делать несколько вещей параллельно, используя фоновые процессы . В качестве общего примера:

 rsync foo machine1: & rsync bar machine2: & rsync baz machine3: & wait 

wait гарантирует, что программа не продвинется дальше этой точки, прежде чем все фоновые процессы, созданные сценарием, будут завершены.

& Идет в самом конце каждой командной строки, так как ; это разделитель команд.