检查数组中的ruby中的挂载点

时间:2017-05-09 21:58:52

标签: ruby linux

警告:Ruby noob

我正在尝试收集文件系统挂载列表,并使用我希望在列表中看到的内容进行交叉检查。所以,如果使用正确的选项挂载sysfs那么好,如果不是那么糟糕。

目前的剧本很难看,但有效。有一个更好的方法吗?我还有十几个挂载点需要检查,但是不想要包含60行代码来执行此操作。

到目前为止我所拥有的:

mounts = []
File.foreach('/proc/mounts') do |line|
  mounts.push line
end

if mounts.include?("rootfs / rootfs rw 0 0\n")
  puts 'rootfs exists'
else
  puts "rootfs doesn't exist"
end


if mounts.include?("sysfs /sys sysfs rw,seclabel,nosuid,nodev,noexec,relatime 0 0\n")
  puts 'sysfs exists'
else
  puts "sysfs doesn't exist"
end

1 个答案:

答案 0 :(得分:2)

这个怎么样:

MOUNT_POINTS = {
  rootfs: "rootfs / rootfs rw 0 0\n",
  sysfs:  "sysfs /sys sysfs rw,seclabel,nosuid,nodev,noexec,relatime 0 0\n"
}

mounts = []
File.foreach('/proc/mounts') { |line| mounts << line }

MOUNT_POINTS.each do |k, v|
  puts mounts.include?(v) ? "#{k} exists" : "#{k} doesn't exist"
end

现在,您只需要将所有挂载点添加到MOUNT_POINTS哈希,并且将迭代所有这些点,并提供所需的输出。

这一行

puts mounts.include?(v) ? "#{k} exists" : "#{k} doesn't exist"

评估mounts.include?(v)puts连结k的消息(其中k密钥v MOUNT_POINTS哈希中当前迭代的值

因此,例如,在第一次迭代中(在当前MOUNT_POINTS哈希中)该行将成为:

puts mounts.include?("rootfs / rootfs rw 0 0\n") ? "rootfs exists" : "rootfs doesn't exist"

使用三元运算符,等效于

if mounts.include?("rootfs / rootfs rw 0 0\n")
 puts "rootfs exists"
else
 puts "rootfs doesn't exist"
end

作为旁注,您可能会注意到我也改变了

File.foreach('/proc/mounts') do |line|
  mounts.push line
end

File.foreach('/proc/mounts') { |line| mounts << line }

两者都完全相同,你可以使用其中任何一个,它只是一种风格问题。

更新(根据评论)

要写入文件,您可以先打开文件,然后运行MOUNT_POINTS次迭代,但请注意,每次打开时使用w选项(如注释中)都会截断文件它;如果您只想在同一个文件中添加更多行,请使用a选项(您可以阅读所有open个选项here)。

因此,您可以将MOUNT_POINTS次迭代用作File.open的块:

File.open("failures", 'a') do |file|
  MOUNT_POINTS.each do |k, v|
    mounts.include?(v) ? puts("#{k} exists") : file << "#{k} doesn't exist\n"
  end
end

此代码将首先打开failures文件,然后遍历MOUNT_POINTS,当mounts.include?(v)true时,它将在控制台上打印"#{k} exists" ,如果它false它将附加(通知我使用a选项)"#{k} doesn't exist\n"到文件中;当迭代结束时,文件将被关闭。

现在,您的代码出了什么问题?

该行

puts mounts.include?(v) ? "#{k} exists" : File.open("failures", 'w') { |file| file.write("#{k} doesn't exist\n") }

相同
if mounts.include?(v)
  puts "#{k} exists"
else
  puts File.open("failures", 'w') { |file| file.write("#{k} doesn't exist\n") }
end

其读作:“如果mounts中存在当前挂载点,则在控制台中打印 挂载点名称 ,否则打开文件,用 挂载点名称替换其所有内容 ,关闭文件并在控制台中打印任何方法(即File.open())返回。“

如果您想知道,“puts进行什么?”请记住puts只是另一种方法,所以当使用三元组时

puts condition? ? "it is true!" : "it is false.."

您只是调用puts方法并根据condition?的评估分配参数,因此在puts "it is true!"时执行puts("it is true!")(或condition)评估为true

好的,我明白了,所以 File.open() 返回了什么?它返回块的值,在这种情况下,写入的长度,因此24

现在,经过这一切,你可能会问? “所以我可以在我的代码中将w更改为a(因此每次文件打开时都不会被删除)并且它会起作用吗?”。答案是,你可以这样做,它会起作用:

puts mounts.include?(v) ? "#{k} exists" : File.open("failures", 'a') { |file| file.write("#{k} doesn't exist\n") }

所以公平地问,为什么所有这些麻烦,如果你可以通过一个简单的调整逃脱?嗯,有三个原因浮现在脑海中:

  1. 在每次迭代中打开和关闭文件效率较低。
  2. 在控制台中打印数字不会添加任何值(并且可能会使其混乱)。
  3. 阅读起来比较困难。
  4. 最后选择你(以及你的团队)更适合的东西,并坚持下去。

    快乐的编码!