如何将 bash 脚本准确地写入 Makefile 中?

cer*_*cem 20 bash make

我喜欢打 bash 脚本,但是如果我准备了多个工具,项目的根目录就塞满了这么多的 shell 脚本。这就是我更喜欢使用 Makefile 的原因。

Makefile 很好。但是,我想像构建常规 bash 脚本一样构建我的 makefile。

例如:

以为自己很快写了一个bash脚本,内容如下:

#!/bin/bash
echo "hello"
cd ~
do-some-work.sh my-parameter
Run Code Online (Sandbox Code Playgroud)

我可以用$ ./my-important-task.sh.

如果我想将该脚本移动到 makefile 中,我应该执行以下操作:

SHELL := /bin/bash 

my-important-task: 
    echo "hello" ;\
    cd ~ ;\
    do-some-work.sh my-parameter
Run Code Online (Sandbox Code Playgroud)

但我想要以下内容:

my-important-task: 
    [[copy and paste the my-important-task.sh file]]
Run Code Online (Sandbox Code Playgroud)

有没有办法实现这个目标?

Gil*_*il' 21

如果您真的想“将 bash 脚本准确地写入 Makefile 中”,那么您需要间接地做到这一点。如果您只是将脚本粘贴到目标行之后,那么您将遇到两个无法绕过的问题:命令行需要用制表符缩进,美元符号需要转义。

如果您使用 GNU make(相对于 BSD make、Solaris make 等),那么您可以使用多行定义语法将您的脚本定义为变量,然后使用value函数来使用变量的原始值,绕过扩展。

此外,正如 skwllsp 所解释的,您需要告诉 make 将每个目标的命令列表作为单个 shell 脚本执行,而不是逐行执行,这可以在 GNU make 中通过定义.ONESHELLtarget 来执行

define my_important_task =
# script goes here
endef

my-important-task: ; $(value my_important_task)

.ONESHELL:
Run Code Online (Sandbox Code Playgroud)


小智 8

https://www.gnu.org/software/make/manual/html_node/One-Shell.html

如果 .ONESHELL 特殊目标出现在 makefile 中的任何位置,则每个目标的所有配方行都将提供给 shell 的单个调用。

您仍然需要在每行的开头放置一个制表符,并将所有美元符号加倍(即替换为脚本中$$$任何地方)。


cas*_*cas 5

如果问题是您的顶级项目目录中挤满了数十个脚本,那么显而易见的解决方案是创建一个子目录(例如称为scripts)来放置它们。

运行它们./scripts/scriptname和/或将脚本目录添加到您的 PATH 中。

如果您仍然希望使用 Makefile 来运行它们,只需创建./scripts/scriptname为这些目标运行的 Makefile 条目即可。例如

my-important-task: 
    ./scripts/my-important-task.sh my-parameter
Run Code Online (Sandbox Code Playgroud)

注意:如果 ./scripts 中的脚本调用同一目录中的其他脚本,则它们需要指定脚本的完整路径,或者在 PATH 中包含脚本目录。