Получение количества слов файла в Ruby и не открытого для Command Injection - PullRequest
0 голосов
/ 30 января 2019

Как узнать количество строк файла в переменной в Ruby, используя команду Unix wc для скорости для очень больших файлов, при этом гарантируя, что это безопасно от внедрения команд с использованием open3, system или чего-то подобного для достижения того же самоговывод как `wc -l < "#{file_path}".to_i`

Ответы [ 2 ]

0 голосов
/ 31 января 2019

Если вы предпочитаете использовать собственную команду оболочки, и вам нужно только escape file_path , в стандартной библиотеке есть класс Shellwords .

Очень легко использовать его в своей задаче:

require 'shellwords'

`wc -l < #{Shellwords.escape(file_path)}`.to_i
0 голосов
/ 31 января 2019

Вероятно, проще всего использовать Open3::capture2:

output, status = Open3::capture2('wc', '-l', file_path)

Тогда вы можете проверить status и при необходимости исправлять ошибки, так как output должно быть что-то вроде" 2342 file_path\n", вы можете получить счет с помощью простого вызова #to_i:

line_count = output.to_i

Если вас не волнует обработка ошибок (что никогда бы не произошло в реальной жизни):

line_count = Open3::capture2('wc', '-l', file_path).first.to_i

Никакая оболочка не будет задействована, никаких проблем с внедрением команд.

Однако это предполагает, что первый wc в вашем PATH - это wc, который вы хотите использовать, так что вы можете захотетьбыть более конкретным:

# Or ensure that your PATH environment variable is sensible.
output, status = Open3::capture2('/usr/bin/wc', '-l', file_path)

Это также предполагает, что вы хотите, чтобы пользователи могли читать любые файлы, которые может выполнять ваш процесс;если это не так, то вам нужно занести в черный / белый список file_path, чтобы убедиться, что это то, что они должны прочитать.

Конечно, если вы идете ко всем этим неприятностям, вы можете также открыть файл и подсчитать строки самостоятельно с помощью пары строк Ruby:

# Or some variation on this and a `rescue` to catch exceptions.
line_count = File.open('Gemfile') { |fp| fp.each_line.count }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...