首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用木偶Facter返回多个自定义事实

使用木偶Facter返回多个自定义事实
EN

Stack Overflow用户
提问于 2013-10-01 23:13:19
回答 1查看 3.2K关注 0票数 2

我试图将系统中的用户添加为傀儡事实。我不是一个ruby程序员,下面的代码正确地生成用户,但是他们的uid都是相同的(密码文件中最后一个条目的uid )。如果uid超出了作用域,我将期望出现一个未知的符号错误,如果Facter.add在结束时只被调用一次,我将期望只有一个用户,最后一个用户,与uid相同。我不明白一个人怎么能在没有另一个人这样做的情况下迭代。

代码语言:javascript
复制
File.open("/etc/passwd", "r") do |passwords|
  while pw_entry = passwords.gets
    user, pw, uid, gid, gecos, home, shell = pw_entry.split(/:/)

    Facter.add("user_" + user) do
      setcode do
        uid
      end
    end
  end
end

在四处闲逛时,我发现另一个人的问题与我几乎完全相同,这就是解决办法(这对我也有用):

代码语言:javascript
复制
require 'etc'

Etc.passwd { |user|

    Facter.add("user_" + user.name) {
      setcode {
        user.uid
      }
    }
}

...however我不明白这有什么区别。它的作用就像对Facter.add块的调用在循环结束时得到缓冲并同时全部运行,以及Etc加载了所有passwd,因此user.uid索引与数组中的时间无关。对于一个程序语言来说,这将是一件很奇怪的事情。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-06 14:10:10

你这样说是对的:

代码语言:javascript
复制
File.open("/etc/passwd", "r") do |passwords|
  while pw_entry = passwords.gets
      user, pw, uid, gid, gecos, home, shell = pw_entry.split(/:/)
      print uid
  end
end

几乎相当于:

代码语言:javascript
复制
require 'etc'
Etc.passwd { |user|
  print uid
}

事实上,这两个红宝石片段将产生完全相同的结果。

唯一的区别是,最后一个方法使用了另一种遍历passwd文件的方法。它使用一个闭包,它接收参数user作为输入。此user是存在于匿名函数范围内的唯一user

现在,关于两种方法之间的区别的问题:

当引用不属于闭包本身的ruby闭包中的变量(即外部变量)时,对该变量符号的引用存储在闭包的代码中。因为在第一种方法中,您在同一范围内重用相同的符号,所以在添加所有事实之后调用闭包的代码时,uid引用了uid的最后一个已知值。这就是所谓的outer variable trap

解决这个问题的一种方法是让每个uid都在它自己的范围内存在。

代码语言:javascript
复制
def addUserFact(passwd_entry)
  user, pw, uid, gid, gecos, home, shell = passwd_entry.split(/:/)   
  Facter.add("user_" + user) do
    setcode do
      uid
    end
   end
end

File.open("C:/cygwin/etc/passwd", "r") do |passwords|
  while pw_entry = passwords.gets
    addUserFact(pw_entry)
  end
end
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19127545

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档