前言:我们有一个复杂的构建过程,发现它在一个系统上工作,而在另一个系统上失败(不幸的是/Murphy,它在 Jenkins 构建服务器上工作,所以问题很长一段时间未被发现)。错误源原来是tar
由某些外部组件将硬链接文件放入文件的顺序:
a
并被b
硬链接和tar
红色,而后来,在提取 tar 文件时,仅a
被提取。当然,当a
第一次归档时,它可以工作,但如果b
是 tar 中的第一个,Cannot hard link
就会出现典型的错误。
当然,我们可以tar cf
使用--hard-dereference
,但这意味着更改外部工具中的脚本(这是要避免的),所以我的问题是不同的:
问题:我们的基本目标是获得独立于系统的可重复结果。目前,tar
环序在一个系统上是可重现的,但在另一系统上可能会随机不同。我们可以tar
在不提供选项tar
或将tar
呼叫拆分为多个呼叫的情况下强制执行文件顺序吗?
目前系统都是 Linux,但有时也可能是 FreeBSD 或 MacOS。
答案1
直接的方法是向 tar 提供来自 stdin 的文件列表,您可以控制该列表(例如先对其进行排序)。
但是,由于您说无法控制 tar 调用,因此您需要一种方法来控制目录条目的顺序。
ls -u
您可以通过运行或查看目录条目的顺序find
。
要创建一个目录,其中的条目按照您想要的方式排序,请创建一个新目录,并按所需的顺序一次复制或移动一个文件。
检查一下find
是否有效。使用脚本实现自动化并使其递归。
最后运行该工具。
答案2
我认为问题归结为您的构建过程分为两部分。
- 机器 A 上的第 1 部分(生成您的成就)
- 第 2 部分(使用您的存档完成构建)在机器 A 上运行,但在机器 B 上失败。
并且你无法创建内容机器 B 上的存档,因此必须在机器 A 上完成。
主意
在第 2 部分构建中添加一个步骤,以便在使用之前将存档清理为已知的顺序。
将文件提取到临时目录中,并按照您的首选顺序创建您自己的存档,在两台计算机 A 和 B 上执行此操作(这将是第 2 部分的步骤 0)。
或者,我的 tar (tar (GNU tar) 1.30) 版本有这个选项:
-s, --preserve-order, --same-order
Sort names to extract to match archive