我有一个名为experiments
的目录和一个带有单独实验的子目录,例如2018-08-20
,2018-08-21
。每个子目录都包含一个我使用以下命令在屏幕上运行的Python脚本:
screen -L -dm -S experiment python script.py
我想知道我是否可以在 Makefile
目录中有一个 experiments
来自动执行该命令。
我知道每个子目录中都可以有一个Makefile
,但这会给git带来太多重复的内容。
答案 0 :(得分:2)
可以。由于您没有提供太多详细信息,因此我认为:
experiments
python脚本的script.py
的make
时重新运行所有实验。以下应该是一个很好的起点:
EXPDIRS := $(dir $(shell find . -maxdepth 2 -mindepth 2 -type f -name script.py))
EXPS := $(addsuffix .done,$(EXPDIRS))
.PHONY: all $(EXPS)
all: $(EXPS)
$(EXPS): %.done:
cd $* && screen -L -dm -S experiment python script.py
说明:
EXPDIRS
实用程序和find
make函数设置dir
make变量(以删除返回路径的文件名部分)。例如:./experimentC/ ./experimentA/
。EXPS
中的每个单词添加.done
来设置EXPDIRS
make变量。例如:./experimentC/.done ./experimentA/.done
。EXPS
中列出的目标以及all
目标被声明为phony,这意味着即使具有该名称的文件已经存在并且是最新的,make也会重新运行其构建规则。 all
取决于EXPS
中列出的所有目标。如果仅运行make
或make all
,则make将运行所有实验的规则,如果您使用-j4
选项调用make,并且有4个内核,则make可能并行运行在您的计算机上。$(EXPS):...
告诉进行该操作以构建EXPS
中列出的目标:
$*
使自动变量随着%.done
模式的茎而扩展)。可能的改进:
仅当尚未运行实验或自上次运行以来其输入数据已更改时,才运行实验。假设输入数据只是python脚本(如果需要,易于修改)。我们将使用一个名为experimentA/.done
的空文件将实验标记为完成并记住何时进行。然后,以下应避免无用的实验运行:
EXPDIRS := $(dir $(shell find . -maxdepth 2 -mindepth 2 -type f -name script.py))
EXPS := $(addsuffix .done,$(EXPDIRS))
.PHONY: all
all: $(EXPS)
$(EXPS): %.done: %script.py
cd $* && screen -L -dm -S experiment python script.py
touch $@
clean:
rm -f $(EXPS)