我使用scp命令将文件从一个Linux主机复制到另一个Linux主机。 我在host1上运行scp commend并将文件从host1复制到host2。文件很大,复制它需要一些时间。 一旦复制开始,就会立即显示host2文件。即使复制仍在进行中,我也可以使用此文件执行所有操作。
有没有可靠的方法来确定主机2上的复制是否已完成?
答案 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
使用CNT
和MAX_CNT
禁用无限循环(如果文件successful
未被转移)。
产品MAX_CNT
和SLEEP_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)
本地和远程文件的校验和(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
答案 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"