2014-03-29 57 views
3

我正在使用scp命令將文件從一臺Linux主機複製到另一臺。 我在主機1上運行scp commend,並將文件從主機1複製到主機2。文件相當大,需要一段時間才能複製。 一旦開始複製,主機2文件立即出現。即使複製仍在進行中,我仍可以使用此文件執行所有操作。scp:如何發現複製已完成

有沒有可靠的方法來確定複製是否完成或不在host2上?

回答

6

關閉我的頭頂,你可以這樣做:

touch tinyfile 
scp bigfile tinyfile [email protected]: 

然後當tinyfile看來你知道的bigfile傳輸完成。

正如評論中指出的那樣,這假定scp將按指定的順序一個接一個地複製文件。如果你不信任它,你可以一個接一個地去做:

scp bigfile [email protected]: 
scp tinyfile [email protected]: 

這種方法的缺點是你可能要驗證兩次。如果這是一個問題,你可以使用像ssh-agent

+1

除非'scp'決定它一次可以複製多個文件。 – jfs

+1

@ J.F.Sebastian我想這是一種可能性,我已經編輯了我的答案 –

3

在發送端(主機1)使用這樣的腳本:

#!/bin/bash 

echo 'starting transfer' 
scp FILE [email protected]_SERVER:DST_PATH 
OUT=$? 
if [ $OUT = 0 ]; then 
    echo 'transfer successful' 
    touch successful 
    scp successful [email protected]_SERVER:DST_PATH 
else 
    echo 'transfer faild' 
fi 

在接收端(主機2)使這樣的腳本:

#!/bin/bash 

SLEEP_TIME=30 
MAX_CNT=10 
CNT=0 
while [[ ! -e successful && $CNT < $MAX_CNT ]]; do 
    ((CNT++)) 

    sleep($SLEEP_TIME); 
done; 

if [[ -e successful ]]; then 
    echo 'successful' 
    rm successful 

    # do somethning with FILE 
fi 

隨着CNTMAX_CNT禁用無限循環(以沒有傳送案件檔案successful)。 產品MAX_CNTSLEEP_TIME應等於或大於預期的轉移時間。在我的例子中,預期的傳輸時間少於300秒。

1

經過一番調查,並在其他論壇上討論這個問題後,我發現了另一個解決方案。也許它可以幫助某人。

有一個命令「lsof」。它列出了打開的文件。在複製該文件將被打開,因此命令

lsof | grep filename

將返回非空的結果。

所以你可能想讓一個while循環等到lsof什麼都不返回並繼續執行你的任務。

# provide your file name here 
f=<nameOfYourFile> 
lsofresult=`lsof | grep $f | wc -l` 
while [ $lsofresult != 0 ]; do 
    echo still copying file $f... 
    sleep 5 
    lsofresult=`lsof | grep $f | wc -l` 
done; echo copying file $f is finished: `ls $f` 
+2

'lsof'將查詢打開文件的所有進程。爲什麼不使用'fuser'直接檢查文件? 'fuser file'將打印具有'file'打開的PID,如果進程是'ssh',那麼它仍然被複制。 「lsof」和「fuser」都不能被依賴,因爲即使中斷,ssh也會使文件保持完整。唯一可靠的方法是在文件關閉後獲取校驗和。在你的問題中,你說「可靠的方式」。 – alvits

0

對於重複的問題,How to check if file has been scp 100% to the remote location,這是一個expect腳本,要知道如果一個文件被完全轉移,我們可以添加預計100%.. ..即東西像這樣...

expect -c " 
    set timeout 1 
    spawn scp [email protected]$REMOTE_IP:/tmp/my.file [email protected]$HOST_IP:/home/. 
    expect yes/no { send yes\r ; exp_continue } 
    expect password: { send $SCP_PASSWORD\r } 
    expect 100% 
    sleep 1 
    exit 
" 
if [ -f "/home/my.file" ]; then 
echo "Success" 
fi 
0

的本地和遠程文件的校驗和(md5sumsha256sumsha512sum)會告訴你,如果他們是相同的。

對於沒有SSH訪問遠程系統的情況 - 比如FTP服務器 - 您可以在文件上傳後下載並比較校驗和。我爲從工作中的生產腳本發送的文件執行此操作。以下是我在其中執行此操作的腳本的一部分內容。

MD5SRC=$(md5sum $LOCALFILE | cut -c 1-32) 
MD5TESTFILE=$(mktemp -p /ramdisk) 
curl \ 
    -o $MD5TESTFILE \ 
    -sS \ 
    -u $FTPUSER:$FTPPASS \ 
    ftp://$FTPHOST/$REMOTEFILE 
MD5DST=$(md5sum $MD5TESTFILE | cut -c 1-32) 
if [ "$MD5SRC" == "$MD5DST" ] 
then 
    echo "+Local and Remote files match!" 
else 
    echo "-Local and Remote files don't match" 
fi 
0

如果避免第二SSH握手是非常重要的,你可以使用類似以下內容:

ssh host cat \> bigfile \&\& touch complete < bigfile 

然後等待「完整」的文件,以獲得在遠端創建的。

相關問題