警告: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
答案 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") }
所以公平地问,为什么所有这些麻烦,如果你可以通过一个简单的调整逃脱?嗯,有三个原因浮现在脑海中:
最后选择你(以及你的团队)更适合的东西,并坚持下去。
快乐的编码!