bash scp:如何知道复制已完成
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22730220/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
scp: how to find out that copying was finished
提问by Sandro
I'm using scp command to copy file from one Linux host to another. I run scp commend on host1 and copy file from host1 to host2. File is quite big and it takes for some time to copy it. On host2 file appears immediately as soon as copying was started. I can do everything with this file even if copying is still in progress.
我正在使用 scp 命令将文件从一台 Linux 主机复制到另一台。我在主机 1 上运行 scp 推荐并将文件从主机 1 复制到主机 2。文件很大,复制它需要一些时间。一旦开始复制,host2 上的文件就会立即出现。即使复制仍在进行中,我也可以对这个文件做任何事情。
Is there any reliable way to find out if copying was finished or not on host2?
是否有任何可靠的方法可以确定在 host2 上复制是否已完成?
回答by Tom Fenech
Off the top of my head, you could do something like:
在我的脑海里,你可以做这样的事情:
touch tinyfile
scp bigfile tinyfile user@host:
Then when tinyfile
appears you know that the transfer of bigfile
is complete.
然后当tinyfile
出现时,您就知道传输bigfile
已完成。
As pointed out in the comments, this assumes that scp
will copy the files one by one, in the order specified. If you don't trust it, you could do them one by one explicitly:
正如评论中指出的那样,这假设scp
将按照指定的顺序一个一个地复制文件。如果你不相信它,你可以明确地一一执行:
scp bigfile user@host:
scp tinyfile user@host:
The disadvantage of this approach is that you would potentially have to authenticate twice. If this were an issue you could use something like ssh-agent.
这种方法的缺点是您可能需要进行两次身份验证。如果这是一个问题,您可以使用类似ssh-agent 的东西。
回答by djm.im
On sending side (host1) use script like this:
在发送端(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
On receiving side (host2) make script like this:
在接收端 (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
With CNT
and MAX_CNT
you disable endless loop (in case file successful
isn't transferred).
Product MAX_CNT
and SLEEP_TIME
should be equal or greater expected transfer time. In my example expected transfer time is less than 300 seconds.
使用CNT
和MAX_CNT
禁用无限循环(以防文件successful
未传输)。产品MAX_CNT
和SLEEP_TIME
应等于或大于预期转移时间。在我的示例中,预期传输时间小于 300 秒。
回答by Sandro
After some investigation, and discussion of the problem on other forums I have found one more solution. Maybe it can help somebody.
经过一番调查,并在其他论坛上讨论了这个问题,我找到了另一种解决方案。也许它可以帮助某人。
There is a command "lsof". It lists open files. During copying the file will be opened, so the command
有一个命令“lsof”。它列出了打开的文件。复制过程中文件会被打开,所以命令
lsof | grep filename
lsof | grep filename
will return non empty result.
将返回非空结果。
So you might want to make a while
loop to wait until lsof returns nothing and proceed with your task.
因此,您可能希望创建一个while
循环以等待 lsof 不返回任何内容并继续执行您的任务。
Example:
示例:
# 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`
回答by user208145
A checksum (md5sum
, sha256sum
,sha512sum
) of the local and remote files would tell you if they're identical.
本地和远程文件的校验和 ( md5sum
, sha256sum
, sha512sum
) 会告诉您它们是否相同。
For the situation where you don't have SSH access to the remote system - like an FTP server - you can download the file after it's uploaded and compare the checksums. I do this for files I send from production scripts at work. Below is a snippet from the script in which I do this.
对于您无法通过 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
回答by Rich Remer
If avoiding a second SSH handshake is important, you can use something like the following:
如果避免第二次 SSH 握手很重要,您可以使用以下内容:
ssh host cat \> bigfile \&\& touch complete < bigfile
Then wait for the "complete" file to get created on the remote end.
然后等待在远程端创建“完整”文件。
回答by molokovskikh
if you use inotify-tools
,
then the solution will looks like this:
如果您使用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"
回答by Nagendra NR
For the duplicate question, How to check if file has been scp 100% to the remote location, which was for an expect script, to know if a file is transferred completely, we can add expect 100% .. .. i.e something like this ...
对于重复的问题,How to check if file has been scp 100% to the remote location,这是一个expect脚本,要知道文件是否完全传输,我们可以添加expect 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