我正在使用scp命令將文件從一臺Linux主機複製到另一臺。 我在主機1上運行scp commend,並將文件從主機1複製到主機2。文件相當大,需要一段時間才能複製。 一旦開始複製,主機2文件立即出現。即使複製仍在進行中,我仍可以使用此文件執行所有操作。scp:如何發現複製已完成
有沒有可靠的方法來確定複製是否完成或不在host2上?
我正在使用scp命令將文件從一臺Linux主機複製到另一臺。 我在主機1上運行scp commend,並將文件從主機1複製到主機2。文件相當大,需要一段時間才能複製。 一旦開始複製,主機2文件立即出現。即使複製仍在進行中,我仍可以使用此文件執行所有操作。scp:如何發現複製已完成
有沒有可靠的方法來確定複製是否完成或不在host2上?
關閉我的頭頂,你可以這樣做:
touch tinyfile
scp bigfile tinyfile [email protected]:
然後當tinyfile
看來你知道的bigfile
傳輸完成。
正如評論中指出的那樣,這假定scp
將按指定的順序一個接一個地複製文件。如果你不信任它,你可以一個接一個地去做:
scp bigfile [email protected]:
scp tinyfile [email protected]:
這種方法的缺點是你可能要驗證兩次。如果這是一個問題,你可以使用像ssh-agent。
在發送端(主機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
隨着CNT
和MAX_CNT
禁用無限循環(以沒有傳送案件檔案successful
)。 產品MAX_CNT
和SLEEP_TIME
應等於或大於預期的轉移時間。在我的例子中,預期的傳輸時間少於300秒。
經過一番調查,並在其他論壇上討論這個問題後,我發現了另一個解決方案。也許它可以幫助某人。
有一個命令「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`
'lsof'將查詢打開文件的所有進程。爲什麼不使用'fuser'直接檢查文件? 'fuser file'將打印具有'file'打開的PID,如果進程是'ssh',那麼它仍然被複制。 「lsof」和「fuser」都不能被依賴,因爲即使中斷,ssh也會使文件保持完整。唯一可靠的方法是在文件關閉後獲取校驗和。在你的問題中,你說「可靠的方式」。 – alvits
對於重複的問題,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
的本地和遠程文件的校驗和(md5sum
,sha256sum
,sha512sum
)會告訴你,如果他們是相同的。
對於沒有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
如果避免第二SSH握手是非常重要的,你可以使用類似以下內容:
ssh host cat \> bigfile \&\& touch complete < bigfile
然後等待「完整」的文件,以獲得在遠端創建的。
除非'scp'決定它一次可以複製多個文件。 – jfs
@ J.F.Sebastian我想這是一種可能性,我已經編輯了我的答案 –