scp:如何找出复制完成

时间:2014-03-29 11:02:43

标签: linux bash shell sh scp

我使用scp命令将文件从一个Linux主机复制到另一个Linux主机。 我在host1上运行scp commend并将文件从host1复制到host2。文件很大,复制它需要一些时间。 一旦复制开始,就会立即显示host2文件。即使复制仍在进行中,我也可以使用此文件执行所有操作。

有没有可靠的方法来确定主机2上的复制是否已完成?

7 个答案:

答案 0 :(得分:8)

在我的头顶,你可以做类似的事情:

touch tinyfile
scp bigfile tinyfile user@host:

然后,当tinyfile出现时,您知道bigfile的转移已完成。

正如评论中所指出的,这假定scp将按指定的顺序逐个复制文件。如果你不信任它,你可以明确地逐一完成它们:

scp bigfile user@host:
scp tinyfile user@host:

这种方法的缺点是您可能需要进行两次身份验证。如果这是一个问题,您可以使用类似ssh-agent的内容。

答案 1 :(得分:3)

在发送方(host1)上使用这样的脚本:

#!/bin/bash

echo 'starting transfer'
scp FILE USER@DST_SERVER:DST_PATH
OUT=$?
if [ $OUT = 0 ]; then
  echo 'transfer successful'
  touch successful
  scp successful USER@DST_SERVER:DST_PATH
else
  echo 'transfer faild'
fi

在接收方(host2)上创建如下脚本:

#!/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秒。

答案 2 :(得分:2)

经过一些调查,并在其他论坛上讨论了这个问题,我找到了另一个解决方案。也许它可以帮助某人。

有一个命令&#34; lsof&#34;。它列出了打开的文件。在复制期间,文件将被打开,因此命令

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`

答案 3 :(得分:2)

本地和远程文件的校验和(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

答案 4 :(得分:1)

对于重复的问题,How to check if file has been scp 100% to the remote location,这是一个期望脚本,要知道文件是否完全传输,我们可以添加期望100%...... ..就像这样......

expect -c "  
   set timeout 1
   spawn scp user@$REMOTE_IP:/tmp/my.file user@$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

答案 5 :(得分:1)

如果避免第二次SSH握手很重要,您可以使用以下内容:

[HttpPost]
public IActionResult SendSMS()
{
    System.Diagnostics.Debug.WriteLine("The form has " + Request.Form);
    return Content("Received");
}

然后等待在远程端创建“完整”文件。

答案 6 :(得分:1)

如果您使用inotify-tools, 那么解决方案将如下所示:

while ! inotifywait -e close $(dirname ${bigfile_fullname}) 2>/dev/null | \
    grep -Eo "CLOSE $(basename ${bigfile_fullname})$">/dev/null
do true
done
echo "File ${bigfile_fullname} closed"