AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 62587
Accepted
sanity
sanity
Asked: 2009-09-05 13:34:00 +0800 CST2009-09-05 13:34:00 +0800 CST 2009-09-05 13:34:00 +0800 CST

通过 bash 管道处理大文件,它会缓冲吗?

  • 772

我需要使用如下命令:

$ cat large.input.file | process.py > large.output.file

问题是,这样硬盘在读取输入文件和写入输出文件之间不会很难跳转吗?

有没有办法告诉 bash 在做这种管道时使用大内存缓冲区?

bash
  • 7 7 个回答
  • 16057 Views

7 个回答

  • Voted
  1. David Spillett
    2009-09-05T14:38:41+08:002009-09-05T14:38:41+08:00

    操作系统会将输出缓冲到一定量,但如果输入和输出文件都在同一个驱动器上,可能仍然会有很多头部翻转,除非你自己process.py做一些缓冲。

    您可以cat在示例中用管道查看器 (pv)替换(在大多数标准存储库中可用,如果它不在您的发行版的存储库中,则可以轻松编译),这允许您将其设置为缓冲更多(使用-B/--buffer-bytes选项)并显示进度条(除非您要求不要这样做),如果您process.py不输出自己的进度信息,这对于长时间操作可能非常方便。对于将数据从驱动器上的一个位置传递到同一驱动器上的另一个位置,这可能会产生很大的不同,除非整个过程主要受 CPU 限制而不是 I/O 限制。

    因此,对于 1Mb 缓冲区,您可以执行以下操作:

    pv -B 1m large.input.file | process.py > large.output.file
    

    我pv一直在使用这种东西,尽管主要用于进度指示器而不是可调整的缓冲区大小。

    另一种选择是使用更“标准”(就默认情况下普遍可用的标准而言,它的命令行格式与大多数常见命令略有不同)dd,尽管它没有进度条功能:

    dd if=large.input.file bs=1048576 | process.py > large.output.file
    

    编辑:ps。吊坠可能会指出cat您的示例中不需要,因为以下内容也可以正常工作并且效率会更高:

    process.py < large.input.file > large.output.file
    

    有些人将取消不必要的电话cat称为“民主化”,这些人可能不应该被鼓励......

    • 8
  2. hurikhan77
    2009-09-05T13:49:14+08:002009-09-05T13:49:14+08:00

    不是有一个旧的 unix 工具叫做“buffer”吗?并不是说今天的缓存技术需要这样做 - 但它就在那里。

    • 5
  3. Best Answer
    Ludwig Weinzierl
    2009-09-05T13:38:39+08:002009-09-05T13:38:39+08:00

    不用担心。操作系统会为你做缓冲,它通常很擅长。

    话虽这么说:如果您可以更改 process.py,则可以实现自己的缓冲。如果您无法更改 process.py,您可以编写自己的 buffer.py 并像这样使用它。

    $ cat large.input.file | buffer.py | process.py | buffer.py > large.output.file
    

    可能更容易从RAM 磁盘读取和写入。

    • 4
  4. mdpc
    2009-09-05T15:46:28+08:002009-09-05T15:46:28+08:00

    我相信用户正在暗示的问题是输入/输出通常如何在 UNIX/Linux 世界中工作。每个 UNIX/Linux 进程基本上一次只能有一个 I/O 操作挂起。因此,在示例中的 cat 命令的情况下,cat 命令首先读取一些数据,等待它完成,然后写入数据并等待它完成,然后再继续。进程中没有并发 I/O,因此缓冲仅在读取和写入之间使用,以简单地临时保存一些数据。

    为了加快速度,输入和输出可以分解为两个不同的进程:一个读取器进程和一个写入器进程,以及用作两个进程之间缓冲区的大量共享内存。这导致了人们想要的并发 I/O,并且可以加快文件传输过程。

    由用户指定的实用程序缓冲区实现了我所描述的这种并发方法。在与磁带驱动器连接以进行备份时,我使用了带有相当大的共享内存缓冲区的缓冲区程序。这导致挂钟传输时间减少了约 20%。

    使用缓冲程序代替“cat”命令可能会带来一些明确的改进……取决于。

    享受!

    • 3
  5. RAKK
    2014-05-21T11:56:26+08:002014-05-21T11:56:26+08:00

    尝试使用我刚刚放在一起的这个 Python 2 小程序:

    #! /usr/bin/python2
    # This executable path is Gentoo-specific, you might need to change it yourself
    
    import sys;
    
    if sys.argv[1].endswith('K'):
       bytestoread = int(sys.argv[1].translate(None, 'K')) * 1024;
    elif sys.argv[1].endswith('M'):
       bytestoread = int(sys.argv[1].translate(None, 'M')) * 1024 * 1024;
    elif sys.argv[1].endswith('G'):
       bytestoread = int(sys.argv[1].translate(None, 'G')) * 1024 * 1024 * 1024;
    
    while True:
       buffer = sys.stdin.read(bytestoread);
       if buffer == '':
          exit();
       sys.stdout.write(buffer);
       buffer = None;   # This one is for making sure the read buffer will get destroyed, otherwise we could bring our system to a halt if we have 8 GB of RAM, request a 5 GB buffer, and it ends up eating 10 GB of memory.
    

    要使用此文件,请像这样调用它:

    cat large.input.file | process.py | buffer.py 2G > large.output.file
    

    您可以使用 2K 指定 2 KB,2M 指定 2 MB,2G 指定 2 GB,如果您愿意,您可以为 2 TB 缓冲区添加 2T:3

    使用 压缩虚拟机映像时,我总是遇到这个问题pigz -1,因为这使得压缩速度非常快,磁盘开始同时读取和写入,并且随着磁盘的磁头开始在输入和输出文件之间呼啸而过,进程减慢到停止. 所以我所做的是制作这个小程序,它从标准输入读取大量数据,将其写入标准输出,然后重复。当读取返回一个空白字符串时,这是因为没有收到更多的标准输入并且脚本完成了。

    • 2
  6. Bill Weiss
    2009-09-05T13:37:41+08:002009-09-05T13:37:41+08:00

    它会智能地缓冲,但没有很好的方法来调整缓冲量。

    您可以编写一个中间程序来执行您想要的缓存并从输入中读取它。

    • 0
  7. X-Istence
    2009-09-05T13:40:01+08:002009-09-05T13:40:01+08:00

    您的操作系统将在将文件写入硬盘驱动器之前对文件进行各种缓存,并且还将对正在读取的文件进行缓存(如果可能,通常会提前读取)。让操作系统进行缓冲和缓存。

    在您可以通过测试和分析证明硬盘驱动器是等式中的限制因素之前,最好不要管它。

    如果您可以更改 process.py,您可以代替直接使用管道读/写来读/写,而是使用缓冲和/或 memmap 文件,这将有助于从系统中移除一些负载。

    • -1

相关问题

  • Mac OS X:从 python 脚本中更改 $PATH

  • Bash 脚本:要求脚本以 root 身份运行(或使用 sudo)

  • crontab ifconfig 什么都不输出

  • 使用命令行工具按排序顺序计算重复项

  • 是否有 bash 等效于 ruby​​ 的“一些内容#{foo}”?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    从 IP 地址解析主机名

    • 8 个回答
  • Marko Smith

    如何按大小对 du -h 输出进行排序

    • 30 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    Windows 中执行反向 DNS 查找的命令行实用程序是什么?

    • 14 个回答
  • Marko Smith

    如何检查 Windows 机器上的端口是否被阻塞?

    • 4 个回答
  • Marko Smith

    我应该打开哪个端口以允许远程桌面?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    MikeN 在 Nginx 中,如何在维护子域的同时将所有 http 请求重写为 https? 2009-09-22 06:04:43 +0800 CST
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    0x89 bash中的双方括号和单方括号有什么区别? 2009-08-10 13:11:51 +0800 CST
  • Martin Hope
    kch 如何更改我的私钥密码? 2009-08-06 21:37:57 +0800 CST
  • Martin Hope
    Kyle Brandt IPv4 子网如何工作? 2009-08-05 06:05:31 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve