首页 > 解决方案 > 在 Ruby 中获取文件的字数并且不打开命令注入

问题描述

如何使用 Unix 命令 wc 将文件的行数获取到 Ruby 中的变量中,以提高超大文件的速度,同时确保使用 open3、system 或类似的东西可以安全地进行命令注入,以实现与`wc -l < "#{file_path}".to_i`

标签: ruby

解决方案


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

不涉及 shell,没有命令注入问题。

但是,这假设您的第一个wcPATHwc要使用的,因此您可能想要更具体:

# 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 }

推荐阅读