Передача вывода команды оболочки в grep вызывает ошибку grep: write

Я написал инструмент в Crystal, который принимает некоторые параметры командной строки и превращает их, по сути, в «find stuff | xargs grep», где xargs указывает использовать несколько процессов. Это запускается через Process.run, а вывод и ошибка перенаправляются в пользовательский объект ввода-вывода, который немного фильтрует то, что выходит из 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"))

person Freezerburn    schedule 24.03.2017    source источник


Ответы (1)


Кажется, теперь это исправлено, поскольку проблема на https://github.com/crystal-lang/crystal/issues/2065 был закрыт. Потребуется провести еще несколько тестов, чтобы убедиться, что он полностью исправлен, но, похоже, сейчас мой старый код работает нормально.

person Freezerburn    schedule 02.06.2017