【问题标题】:Sending command output to a unique file using xargs in Bash在 Bash 中使用 xargs 将命令输出发送到唯一文件
【发布时间】:2016-12-14 12:22:09
【问题描述】:

我正在尝试在固定数量的处理器上动态运行多个进程。我想将输出打印到每个进程的唯一文件,但是 xargs 存在一些问题,它不使用就地文件名为每个进程创建单独的文件。

Bash 脚本调用一个 Csh 脚本,如下:

$ cat temp | xargs -P 8 % csh '%'.csh >& '%'.log

其中 temp 是 csh 命令名称的文本文件。

我的问题是 xargs 从字面上理解 %.log 并在进程写入文件时不断覆盖该文件,而不是根据需要使用单独的 .log 文件。

我以$ bash run.bash & 运行此脚本

【问题讨论】:

    标签: linux xargs


    【解决方案1】:

    一般来说,使用字符串替换来替换代码是一个坏主意——在您的情况下,如果您有一个带有恶意名称的脚本,那么该名称可用于运行任意命令。 (当然,您正在执行脚本,但同样适用于您纯粹处理数据和输出文件名的情况——因此最好养成使用稳健方法的习惯)。

    将名称​​作为参数传递给脚本,而不是将它们替换到脚本中(如果您通过添加@987654322 来修复它的用法,xargs 会这样做@或-J参数:

    # best-practice approach: run a completely fixed shell script, passing arguments on
    # its command line.
    xargs -P 8 -n 1 \
      sh -c 'for x; do csh "${x}.csh" >"${x}.log" 2>&1; done' _
    

    您会注意到调用了sh -c 实例:这是必需的,因为xargs 本身不理解诸如重定向之类的shell 操作;如果你想执行重定向,你需要一个 shell 来做。


    现在,让我们更深入地了解一下为什么您的原始代码会这样:

    xargs -P 8 % csh '%'.csh >& '%'.log
    

    ...首先执行重定向到%.log然后运行命令

    xargs -P 8 % csh '%'.csh
    

    xargs 没有机会替换 %.log 字符串,因为该重定向是由封闭的 shell xargs 命令运行之前执行的。

    【讨论】:

    • 感谢您的详细解答。
    • @WillPhilpott,如果这完全解决了您的问题,请考虑单击答案旁边的复选框以标记该问题已回答。
    【解决方案2】:

    使用 GNU Parallel 它看起来像这样:

    cat temp | parallel -P 8 'csh {}.csh >& {}.log'
    

    如果你有 8 个核心,你甚至可以这样做:

    cat temp | parallel 'csh {}.csh >& {}.log'
    

    GNU 并行引号 {} 以便不会执行恶意输入。

    【讨论】:

      猜你喜欢
      • 2018-09-25
      • 1970-01-01
      • 2018-06-17
      • 1970-01-01
      • 1970-01-01
      • 2013-06-28
      • 2010-12-29
      • 2017-09-17
      • 2010-10-22
      相关资源
      最近更新 更多