如何在 bash shell 腳本中一次複製三個文件而不是一個文件?
我正在執行我的 shell 腳本,在該腳本上將
machineA
文件複製machineB
到.machineC``machineA
如果該文件不在 中
machineB
,那麼它肯定應該在其中machineC
。所以我會先嘗試複製文件machineB
,如果它不在那裡,machineB
那麼我會去machineC
複制相同的文件。在這個文件夾
machineB
裡面machineC
會有一個像這樣的YYYYMMDD
文件夾 -/data/pe_t1_snapshot
因此,無論日期是上述文件夾中這種格式的最新日期
YYYYMMDD
- 我都會選擇該文件夾作為我需要開始復製文件的完整路徑 -
20140317
所以假設如果這是裡面的最新日期文件夾,/data/pe_t1_snapshot
那麼這將是我的完整路徑 -/data/pe_t1_snapshot/20140317
從我需要開始將文件複製到
machineB
和machineC
. 我需要從和復製400
文件,每個文件大小都是.machineA``machineB``machineC``2.5 GB
早些時候,我試圖一個一個地複製文件,
machineA
這真的很慢。有什麼辦法,我可以machineA
在 bash shell 腳本中使用執行緒一次複製“三個”文件?
machineA
下面是我的 shell 腳本,它從machineB
和中一一複製文件machineC
。#!/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
所以我在想而不是一次複製一個文件,為什麼不一次複製“三個”文件,一旦這三個文件完成,我將移動到列表中的另外三個文件同時複製?
我嘗試打開三個 putty 實例,並同時從這三個實例中複製一個文件。所有三個文件都在大約 50 秒內被複製,所以這對我來說很快。由於這個原因,我試圖一次複製三個文件而不是一次複製一個文件。
這可能嗎?如果是,那麼任何人都可以提供一個例子嗎?我只是想試一試,看看效果如何。
@terdon 幫助我完成了上述解決方案,但我想嘗試一次複製三個文件以查看它的行為。
更新:-
下面是上述 shell 腳本的簡化版本。當
machineB
我machineC
在. _ 它將嘗試複製存在於.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)時,如果瓶頸在 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 連接有不可避免的延遲。您可以通過保持連接打開並重複使用它來節省一點時間,這要歸功於主連接。