首先,请注意这是不是一个简单的“合并两个目录”,这是一个关于如何在源更改时保持所述目录的合并更新的问题。
假设我有两个目录a
,b
并且我想c
按照以下规则将它们合并:
- 条目
a
必须始终位于,c
无论其存在或上次修改时间戳。 - 填补空白
b
。
一个简单的cp
fromb
到c
并在必要时用 覆盖a
即可完成工作(复制超过必要的内容,但仅使用一次)
现在,我想要的是某种方法来保持更新(因为这应该在 a 中Makefile
)所以,如果 中有一个新文件a
,make
则复制它。如果 中有新文件b
,make
则复制它仅有的如果它尚未在c
.如果a
更新了来自的文件,make
则将其更新为c
,如果更新了来自的文件b
,则将其更新为c
仅有的如果它来自b
但是不是如果它来自a
.
我希望我已经准确地解释了它。
答案1
达到所需状态的简单解决方案。您可以使用以下 2 个命令:
rsync -auv b/ c/
rsync -av a/ c/
优点:它对所有子目录树递归地工作。
缺点:从你启动第一个命令到第二个命令执行结束的这段时间里,“b/”中一些与“a/”类似的较新文件可以暂时放入“c/”中,直到它们被替换通过第二个命令从“a/”中获取正确的文件。
因此,只有满足以下条件,该解决方案才是好的:
- 您需要最终结果,而不关心同步过程中的“c/”状态;
- 如果您不关心某些文件需要额外复制几次。
答案2
您可以以此Makefile
作为开始。
我用 GNU Make 4.2.1 对其进行了一些测试。我不知道它是否可以与其他 Make 版本一起使用。我知道如果a
或中有子目录,它就会失败b
。也许还有其他陷阱。
.PHONY: all
SRCA = a
SRCB = b
DEST = c
# create list of targets from wildcard lists of both sources
TARGETS = $(patsubst $(SRCA)/%,$(DEST)/%,$(wildcard $(SRCA)/*)) $(patsubst $(SRCB)/%,$(DEST)/%,$(wildcard $(SRCB)/*))
all: $(TARGETS)
# GNU Make prefers the first matching pattern rule because both rules lead to the same stem length
$(DEST)/%:$(SRCA)/%
cp "$<" "$@"
# alternative pattern rule if the first one does not match
$(DEST)/%:$(SRCB)/%
cp "$<" "$@"