在Ruby中获取文件的字数并且无法打开命令注入

时间:2019-01-30 20:34:19

标签: ruby

如何使用Unix命令wc将文件的行数转换为Ruby中的变量,以提高超大文件的速度,同时确保使用open3,system或类似方法进行命令注入是安全的输出为`wc -l < "#{file_path}".to_i`

2 个答案:

答案 0 :(得分:1)

可能最简单的方法是使用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 }

答案 1 :(得分:0)

如果您更喜欢使用本机shell命令,而唯一想要的是转义 file_path ,则标准库中有一个Shellwords类。

在任务中使用它非常容易:

require 'shellwords'

`wc -l < #{Shellwords.escape(file_path)}`.to_i