( fuse-zip )使用 cp 报告虚拟内存不足

( fuse-zip )使用 cp 报告虚拟内存不足

你好我正在使用这个命令

find ./"DCIM/Camera" -name "Camera" -print -exec cp -n -a -p -R -v "{}" "/home/username/path/to/destination/folder" \;

使用 fuse-zip 将文件和文件夹从作为文件夹安装的 zip 文件复制到另一个 fuse-zip 文件夹。Camera/ 文件夹中总共有 1,524 个文件。一段时间后,我的电脑变热,风扇旋转得更快,屏幕顶部出现此错误

虚拟终端已停止 设备内存几乎已满。虚拟终端进程占用了大量内存,因此被迫停止。

在终端收到的错误消息是

cp: error copying '...': Transport endpoint is not connected

奇怪的是,当我将目标设置为 home/username/Documents -- 本地文件夹时,整个复制过程完成时没有错误或中断。我有 16 GB 的 RAM。在 fuse-zip 文件夹内复制时会出现什么问题?为什么会出现问题?

答案1

忽视您的搜索/复制方法,因为它们似乎与您遇到的错误无关。

好的!...我以前从来没有尝试过这个...但是,猜怎么着...我忍不住几分钟前就尝试过了,结果如下。

$ # Make mount points
$ mkdir fuse_mount1 fuse_mount2
$ # Create 2000 files of 1M each
$ truncate -s 1M file{0000..1999}
$ # Zip each 1000 files in a different archive
$ zip archive1 file{0000..0999}
$ zip archive2 file{1000..1999}
$ # Mount both the archives
$ fuse-zip archive1.zip fuse_mount1/
$ fuse-zip archive2.zip fuse_mount2/
$ # Copy "fuse_mount1" under "fuse_mount2"
$ cp -n -a -r ./fuse_mount1 ./fuse_mount2
$ # Unmount the two fuse filesystems
$ fusermount -u fuse_mount1/
$ fusermount -u fuse_mount2/

需要大约1G我的测试机的 RAM 为 20G ...所以,没有什么不正常的。

因此,我改变了公式:

$ # remove previous files and archives
$ rm file* *.zip*
$ # Create 200 files of 100M each
$ truncate -s 100M file{000..199}
$ # Zip each 100 file in a different archive
$ zip archive1 file{000..099}
$ zip archive2 file{100..199}
$ # Mount both the archives
$ fuse-zip archive1.zip fuse_mount1/
$ fuse-zip archive2.zip fuse_mount2/
$ # Copy "fuse_mount1" under "fuse_mount2"
$ cp -n -a -r ./fuse_mount1 ./fuse_mount2
$ # Unmount the two fuse filesystems
$ fusermount -u fuse_mount1/
$ fusermount -u fuse_mount2/

需要大约10G我的测试机器的 RAM 为 20G...这不是一般消费机器可以处理的。

底线是,fuse-zip在某些情况下可以使用/需要大量内存,如果您的 RAM 内存有限甚至是平均水平,那么不建议执行复制等大文件/海量文件操作,并且可能会由于耗尽系统内存而无法工作。

我确实使用了调试选项,即fuse-zip -d …从其他终端挂载档案,并注意到目标挂载上的过多日志记录cp似乎打印了大量的内存地址,这表明目标上的内存使用量很大,而fuse_mount2源挂载上的内存使用量似乎要少得多...我还没有时间深入研究它,但你可以这样做,并在启用调试的情况下进行更多调查...所以,看起来从挂载中复制所需的内存比复制到挂载要少fuse-zip

这实际上是在fuse-zip项目页面

添加/更改的文件将驻留在内存中,直到您卸载文件系统。

添加/解压非常大的文件(超过可用内存的一半)可能会导致系统交换。在这种情况下,使用 zip/unzip 是个好主意 :)

这解释了整件事。

因此,对于这样的操作,请提取档案,对其进行任何您想做的事情,然后再次压缩它们。

但是,如果你无论如何都必须按照自己的方式去做……那么,在监视内存使用情况的同时复制一些文件,当内存接近满时,停止复制并卸载目标fuse-zip挂载,等待它完成处理,然后再次挂载它以复制另一批文件等等……但是,我不知道有什么工具可以让你自动做到这一点……所以,我写了这个bash函数(防错能力很弱,它只是一个模板):

fzcp ()
{
    [ -z "$1" ] || [ -z "$2" ] && echo "Insufficient arguments" >&2 && return 1
    source="${1%/}"
    target="${2%/}"

    read -r -p "What is the full pathe to the target fuse-zip mount point? : " mount_point
    read -r -p 'What is the full path(including filename) to the ZIP archive mounted on it? : ' zip_file
    [ -z "$mount_point" ] || [ -z "$zip_file" ] && echo "Insufficient arguments" >&2 && return 1

    total_m=$(free | awk '/Mem:/{print $2}')
    total_m_percent=$(("$total_m" / 100))

    shopt -s globstar

    for f in "$source"/**/*
      do
        [ -f "$f" ] || continue
        free_m=$(free | awk '/Mem:/{print $7}')
        free_m_percent=$(("$free_m" / "$total_m_percent"))
        if [ "$free_m_percent" -lt 20 ]
          then
            echo "Unmounting $mount_point ..."
            fusermount -u "$mount_point" || break
            while pkill -0 -f "${zip_file##*/}"
              do
                printf "%s\r" "$(date) :: Waiting for fuse-zip to finish adding copied files to $zip_file ..."
                sleep 1
                done
            echo
            echo "Mounting $zip_file on $mount_point ..."
            fuse-zip "$zip_file" "$mount_point" || break
            fi
        cp -n -v --preserve=all --parents -- "$f" "$target"
        done
        
    shopt -u globstar
}

其工作原理如下cp但不接受选项),但对于复制到目标fuse-zip挂载点...它需要两个参数并且像这样使用:

fzcp ./fuse_mount1/source_directory /home/user/fuse_mount2/target_directory

然后它会要求你提供目标fuse-zip挂载的路径和挂载在其上的 ZIP 文件的路径...然后它会完成工作...在依赖它复制重要数据之前,请先测试它以熟悉它的工作原理...将在目标上创建的父目录取决于您提供的源目录路径,因此从源目录的第一个/最近的父目录运行该函数并提供尽可能短的路径,这样应该./source_dorectory只会提供此目录及其子目录的树,但不包括到其根目录的实际完整系统路径/

相关内容