xargs:以并行模式将标准输出重定向到文件时丢失输出

2023-11-23

我在并行模式下使用 GNU xargs(版本 4.2.2),并且在重定向到文件时似乎确实会丢失输出。当重定向到管道时,它似乎工作正常。

以下 shell 命令演示了最小、完整且可验证的示例的问题。我使用生成 2550 个数字xargs将其分成 100 个参数的行,每行总共 26 行,其中第 26 行仅包含 50 个参数。

# generate numbers 1 to 2550 where each number is on its own line
$ seq 1 2550 > /tmp/nums
$ wc -l /tmp/nums
2550 /tmp/nums

# piping to wc is accurate: 26 lines, 2550 args
$ xargs -P20 -n 100 </tmp/nums | wc
     26    2550   11643

# redirecting to a file is clearly inaccurate: 22 lines, 2150 args
$ xargs -P20 -n 100 </tmp/nums >/tmp/out; wc /tmp/out
     22  2150 10043 /tmp/out

我相信问题与底层 shell 无关,因为 shell 将在命令执行之前执行重定向并等待 xargs 完成。在这种情况下,我假设 xargs 在刷新缓冲区之前完成。但是,如果我的假设是正确的,我不知道为什么在写入管道时这个问题没有显现出来。

Edit:

使用时出现>>(创建/附加到文件)在 shell 中,问题似乎没有显现出来:

# appending to file
$ >/tmp/out
$ xargs -P20 -n 100 </tmp/nums >>/tmp/out; wc /tmp/out
     26    2550   11643

# creating and appending to file
$ rm /tmp/out
$ xargs -P20 -n 100 </tmp/nums >>/tmp/out; wc /tmp/out
     26    2550   11643

您的问题是由于不同进程的输出混合所致。如下所示:

parallel perl -e '\$a=\"1{}\"x10000000\;print\ \$a,\"\\n\"' '>' {} ::: a b c d e f
ls -l a b c d e f
parallel -kP4 -n1 grep 1 > out.par ::: a b c d e f
echo a b c d e f | xargs -P4 -n1 grep 1 > out.xargs-unbuf
echo a b c d e f | xargs -P4 -n1 grep --line-buffered 1 > out.xargs-linebuf
echo a b c d e f | xargs -n1 grep 1 > out.xargs-serial
ls -l out*
md5sum out*

解决方案是缓冲每个作业的输出 - 无论是在内存中还是在 tmpfiles 中(就像 GNU Parallel 所做的那样)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

xargs:以并行模式将标准输出重定向到文件时丢失输出 的相关文章

  • bash:使用 scp 检查远程文件是否存在

    我正在编写一个 bash 脚本来将文件从远程服务器复制到本地计算机 我需要检查该文件是否可用 以便在该文件不存在时可以采取替代操作 我知道如何测试本地文件是否存在 但是 使用 scp 会使事情变得有点复杂 常识告诉我 一种方法是无论如何尝试
  • sed(和其他)会损坏非 ASCII 文件吗?

    如果我编写一些操作文件的脚本 例如使用 sed 进行搜索 替换 并且文件可以采用各种字符集 那么文件是否会损坏 我希望替换的文本是 ASCII 并且也仅出现在仅包含 ASCII 的文件中的行上 但其余行包含其他字符集中的字符 如果您的字符集
  • VSCode 集成终端不加载 .bashrc 或 .bash_profile

    我有以下文件来处理 shell 配置 bash profile if f bashrc then source bashrc fi and bashrc configure shell 如果我使用以下命令从命令行打开 VSCodecode
  • 仅当程序成功时如何重定向程序的输出?

    当我的程序之一返回非零退出代码时 我想避免重定向其输出 这可能吗 如果可以 我该怎么做 我失败的尝试 echo foo gt file false cat gt file 这导致file是空的 我想要的行为只是调整file当程序成功时 我还
  • Bash:执行命令时超时/文件溢出终止

    我正在用 bash 编写一个模拟评分脚本 它应该执行一个 C 程序 该程序将给出一些输出 我将其重定向到一个文件 我试图 1 使其在一定持续时间后超时 并且 2 如果输出文件到达某个文件则终止尺寸限制 不知道如何解决这两个问题 有什么帮助吗
  • 文件头中 shebang 的用法:是否有任何选项可以在 shebang 中传递多个参数

    我使用不同的命名空间来执行 python 文件 使用 shebang hashbang 来执行此脚本 bin bash c 面临的问题是 shebang 只接受一个参数 即使我传递多个参数 它也会将其视为单个字符串 舍邦使用 sbin ip
  • 使用 Python 的 Popen 替换 Bash 风格的进程

    在 Bash 中 您可以轻松地将进程的输出重定向到临时文件描述符 并且所有这些都由 bash 自动处理 如下所示 mydaemon config file lt echo autostart True n daemonize True 或者
  • 自动接受安装 NPX 包 [重复]

    这个问题在这里已经有答案了 运行 NPM 包时npx第一次会出现提示询问是否要下载包 例如 如果您运行命令npx some npm package 您会收到以下提示 Need to install the following package
  • Bash:使用参数扩展查找和替换

    我想更换输入法 find string include 圆进度 38px 30px 4eb630 和输出 输出字符串 include 圆进度 38px 30px using find string pattern replacement s
  • 具有此处文档重定向的 Makefile 配方

    有谁知道如何在菜谱上使用此处文档重定向 test sh lt
  • 如何判断输入来自哪个键盘

    设想 我有一个 USB RFID 读取器 将其连接到笔记本电脑后 它可以用作新连接的 USB 键盘 例如无需安装任何驱动程序 当接触带有 RFID 标签的阅读器时 它进入我当前的窗口 例如终端 外壳 RFID 号码 例如0009339384
  • grep 以特定字符串开头的行

    我想找到文件中以特定字符串开头的所有行 问题是 我事先不知道字符串里有什么 该值存储在变量中 天真的解决方案如下 grep my string file txt 因为如果 Bash 变量my string包含任何正则表达式特殊字符 grep
  • SQLPlus 中的运行循环

    我制作了一个 bash 脚本 它通过 SQLPlus 连接到数据库并运行一个包含 For 循环的 SQL 脚本 如下所示 但是一旦运行它 它就会卡在循环的 BEGIN 中 如下所示 我尝试直接通过SQLPlus运行 结果是一样的 那么任何人
  • OS X bash:目录名

    我想创建一个简单的 bash 脚本来在 OS X 上启动 Java 程序 文件名 文件路径和直接工作文件夹都包含空格 当我这样做时 bin sh cd dirname 0 I get usage dirname path 我也尝试过在各种不
  • 当远程(Http)文件更改时如何执行操作?

    我想创建一个脚本 用于检查 URL 并在远程文件的 Last Modified 标头更改时执行操作 下载 解压缩 我考虑过使用curl 获取标头 但随后我必须将其存储在每个文件的某个位置并执行日期比较 有没有人对使用 大部分 标准 UNIX
  • 为什么我不能用这个循环从 bash 历史记录中删除多个条目

    这个循环将显示我想要做的事情 但是如果我删除echo从中 它实际上不会删除任何内容 history grep 0 5 0 9 ls cut c1 5 while read id do echo history d id done 我添加了缩
  • 安装heroku toolbelt后出现Ruby错误

    我正在 win 7 32 位系统上使用 Heroku 但我没有管理员权限 我已经下载并安装了heroku工具带如下http community webfaction com questions 11803 heroku toolbelt h
  • Emacs shell:保存提交消息

    我几天前开始使用 emacs 在 emacs shell M x shell 中使用 git 时遇到问题 当我 git commit 或 git commit amend 时 它会打开 vim 来编辑并保存提交消息 我对此表示同意 但我找不
  • Shell脚本通过curl调用API并处理响应

    我需要创建一个通过curl 调用我的登录API 的shell 脚本 该脚本应该能够存储和处理来自curl api 调用的响应 myscript sh bin bash echo Extract bearer token from curl
  • 错误:选项“Z”仅在夜间编译器上被接受[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我正在通过斯坦福操作系统课程 cs140e https web stanford edu class cs140e 其中一个问题是 有一个名

随机推荐