Tar 使用进度条并处理多卷

Tar 使用进度条并处理多卷

我正在尝试将大型 LVM 卷的 tar 复制到多个外部驱动器上。这部分已经解决了。现在,由于这是一个漫长的过程,我想要一个进度条。从这里的优秀文章来看,我已经接近目标了。

问题是,第一个卷填满后,PV 栏会停止。我希望 PV 在交换磁盘后继续更新。有人知道如何解决这个问题吗?

这是我尝试过的方法。我认为问题出在最后一行代码上。我不确定这种策略是否真的适用于多卷。

代码 ExtBackup.sh:

#!/bin/sh

changedisk()
{
# This routine is called when tar runs out of disk space
# It simply waits for operator to change and mount disks
# then updates the file handle with a new volume number.
echo "Change disks now!" 
read -p "Press <enter> when new disk is mounted. ..." NULL
echo ""

# Update the file name with the new volume number
name=`expr $TAR_ARCHIVE : '\(.*\)-.*'`
echo ${name:-$TAR_ARCHIVE}-Vol$TAR_VOLUME.tar >&$TAR_FD
}

###########
## MAIN  ##
###########

# Test for recursive call to change disks
if [ "$1" = 'changedisk' ]; then 
        changedisk
        exit 0;
fi

# If this is initial call, set SIZE to calculate bytes in source    
SIZE=`du -sb *Folder_Name* | cut -f 1`

# Now TAR it, using Multi-volume option and pipe through PV for progress bar
tar -cM -F 'sh ExtBackup.sh changedisk' *Folder_Name* | \
pv -s ${SIZE} > LVMBackup-$(date +%m-%d-%y)-Vol1.tar

答案1

好吧,我花了一些时间才明白它tar -F实际上做了什么(有任何记录吗?我只是读了源代码),但我认为我为你找到了一个非常好的解决方案。

由于pv不支持假装已经取得了某个进展,我需要用一个类似的工具来替换它bar(在 Debian 中以这个名字提供,或者看看它可怕的主页)。

我发现的解决方案是将所有附加卷的数据通过命名管道 (FIFO) 传递,以将调用bar注入流中。为了避免在新行中打印每个卷的进度条,我使用“tput”在每个卷之后将光标移回上部。

在您的代码中,您将用以下内容替换最后一行changedisk()。(为了简洁起见,这有点不合时宜;一旦您明白了,只需对其进行自定义即可)

tput cuu1 >&2 # clear previous progress bar
(cat somefifo | bar -ns \
    --size "$SIZE" \
    --completed $(((${TAR_VOLUME}-1)*${VOLSIZE})) \
    > ${name:-$TAR_ARCHIVE}-Vol$TAR_VOLUME.tar) &
echo somefifo >&$TAR_FD

并将pv脚本最后一行的调用替换为bar -ns --size ${SIZE}

为了使其工作,您需要将其放在exportSIZE 定义前面,当然还要mkfifo somefifo事先执行。确保您还保护了 FIFO 的权限位。您可能还想考虑使用mktemp来安全地创建临时管道。我想这取决于您的情况。

我使用了一个尚未定义的变量$VOLSIZE,该变量应扩展为卷的大小(以字节为单位)。我不确定在您的设置中如何确定这一点。也许您需要在这里做一些更复杂的事情,例如跟踪所有先前卷大小的累计总和。

相关内容