shell 命令的管道输出到 grep 导致 "grep: write error"

Piping output of shell command to grep causes "grep: write error"

我在 Crystal 中编写了一个工具,它接受一些命令行参数,并将这些参数基本上转换为 "find stuff | xargs grep",其中 xargs 被指示使用多个进程。这是通过 Process.run 实现的 运行,输出和错误被重定向到自定义 IO 对象中,该对象稍微过滤 grep 的内容,将未过滤的所有内容写入 STDOUT。

当我运行正常时,它似乎运行很好。虽然在搜索完成之前似乎确实有一些输出被切断的实例,所以我不确定我是否可以完全相信结果。但是,当我将此命令的输出通过管道传输到 grep 时,它总是提前终止搜索并显示 "grep: write error"。我不知道为什么会这样,希望得到一些帮助。最终我可能会重写它以纯 Crystal 完成所有事情,但现在这是搜索我正在处理的代码库的快速解决方案。

这是获取 运行:

的代码
class FindFilterIO
include IO

@@generic_filter = [".diff", ".iml", "/target/"]
@@web_filter = [".css", ".js", ".jsp", ".ftl"]

def initialize(@web_search : Bool = false)
end

def read(slice : Bytes)
  raise "FindFilterIO does not support reading!"
end

def write(slice : Bytes)
  str = String.new slice
  if @@generic_filter.any? { |e| str.includes? e }
    return
  end

  if @web_search
    if !@@web_filter.any? { |e| str.includes? e }
      return
    end
  end

  STDOUT.write(slice)
end
end

  cmd = "find . -not \( -path ./.svn  -prune \) " \
        "-not \( -path ./.idea -prune \) " \
        "-type f -print0 " \
        "| xargs -0 -P 1 -n 100 grep -E -n --color=always "
  cmd += if @html_id
           "'id=['\"'\"'\"]#{@search_text}['\"'\"'\"]|\##{@search_text}'"
         elsif @html_class
           "'class=['\"'\"'\"]#{@search_text}['\"'\"'\"]|\.#{@search_text}'"
         else
           "'#{@search_text}'"
         end
  io = FindFilterIO.new web_search: (@html_id || @html_class)
  Process.run(cmd, output: io, error: io, shell: true, chdir: File.join(@env.home_dir, @env.branch, "repodir"))

现在 https://github.com/crystal-lang/crystal/issues/2065 的问题已经解决,这似乎已经解决。需要做更多的测试以确保它完全修复,但使用我的旧代码现在似乎工作正常。