我运行一个托pipe的持续集成公司,我们在Linux上运行客户的代码。 我们每次运行代码时,都会在单独的虚拟机中运行它。 一个常见的问题是客户的testing有时会失败,因为他们的代码在虚拟机上签出的目录顺序。
让我进入更多的细节。 在OSX上,HFS +文件系统确保目录始终以相同的顺序遍历。 使用OSX的程序员假设,如果它在机器上运行,它必须在任何地方工作。 但是它在Linux上通常不起作用,因为Linux文件系统在遍历目录时不提供sorting保证。
作为一个例子,考虑有2个文件,a.rb,b.rb. a.rb定义MyObject ,而b.rb使用MyObject 。 如果首先加载a.rb,一切都将工作。 如果b.rb首先被加载,它将尝试访问未定义的variablesMyObject ,并失败。
但比这更糟的是,它并不总是失败。 因为在Linux上订购的文件系统没有sorting,所以在不同的机器上将会是不同的顺序。 这更糟,因为有时testing通过,有时会失败。 这是最糟糕的结果。
所以我的问题是,有没有办法使文件系统的sorting是可重复的。 也许有一些标志ext4,这说明它会一直以某种顺序遍历目录? 或者也许有不同的文件系统有这个保证?
我知道这不是你正在寻找的答案,但我相信正确的解决scheme是避免依赖目录中的文件的顺序。 也许它在所有的HFS +文件系统中总是一致的,也许你可以find一种方法使它在ext4或者其他一些文件系统中保持一致,但是从长远来看,这会比你节省更多的麻烦。 其他人使用你的应用程序会遇到一个令人讨厌的惊喜,当他们没有意识到它只与某些types的文件系统兼容,而不是其他的。 如果文件系统从备份中恢复,则顺序可能会更改。 您可能会遇到兼容性问题,因为HFS +一致性顺序和ext4一致性顺序可能不一样。
只要阅读所有的目录条目并按照字典顺序对列表进行sorting即可。 就像ls一样。
你提到的文件是a.rb和b.rb ,但是如果我们谈论的是编程语言源文件,那么每个文件都不应该负责确保它导入所有的依赖关系吗?
Linux中的POSIX调用readdir()不保证任何一致的顺序。 如果您想要订购结果,则处理文件的应用程序负责订购如何将其呈现给调用函数。
https://stackoverflow.com/questions/8977441/does-readdir-guarantee-an-order
现在,既然你说这是你的客户的代码,你不能修复它,你可能会改变用来提供一致的readdir()调用的链接库。 这将需要一些工作,值得自己的问题。 有关快速参考,请参阅http://www.ibm.com/developerworks/linux/library/l-glibc/index.html 。
改变这可能会产生一些我可能无法预见的其他一系列问题。 你强烈的警告,但如果你的客户不能正确教育,这可能是一个解决scheme。
教育你的客户,有一个固有的顺序依赖应该明确说明。 提供帮助客户在所有系统上进行编译的方式表示依赖关系,并让客户采用捕获编译顺序依赖关系的变化stream程。
如果客户希望能够在其他机器上编译,那么认为它是免费的。
现代Linux(ext4)为文件列表添加了B树索引。 他的一个效果就是默认的文件顺序依赖于他们名字的散列。
要禁用此function,请使用:
tune2fs -O ^ dir_index