![如何将 bash 脚本准确写入 Makefile 中?](https://linux22.com/image/85873/%E5%A6%82%E4%BD%95%E5%B0%86%20bash%20%E8%84%9A%E6%9C%AC%E5%87%86%E7%A1%AE%E5%86%99%E5%85%A5%20Makefile%20%E4%B8%AD%EF%BC%9F.png)
我喜欢敲bash脚本,但是如果我准备多个工具,项目的根目录就会充满很多shell脚本。这就是为什么我更喜欢使用 Makefile。
Makefile 很好。不过,我想像常规 bash 脚本一样构建我的 makefile。
例如:
想想我很快就写了一个bash脚本,内容如下:
#!/bin/bash
echo "hello"
cd ~
do-some-work.sh my-parameter
我可以使用 运行这个脚本$ ./my-important-task.sh
。
如果我想将该脚本移至 makefile 中,我应该执行以下操作:
SHELL := /bin/bash
my-important-task:
echo "hello" ;\
cd ~ ;\
do-some-work.sh my-parameter
但我想要以下内容:
my-important-task:
[[copy and paste the my-important-task.sh file]]
有办法实现这个目标吗?
答案1
如果你真的想“将 bash 脚本准确地写入 Makefiles”,那么你需要间接地完成它。如果您只是将脚本粘贴到目标行之后,那么您将遇到两个无法绕过的问题:命令行需要使用制表符缩进,并且美元符号需要转义。
如果您使用 GNU make(而不是 BSD make、Solaris make 等),那么您可以使用以下命令将脚本定义为变量:多行定义语法,然后使用value
功能使用变量的原始值,绕过扩展。
此外,正如 skwllsp 所解释的,您需要告诉 make 将每个目标的命令列表作为单个 shell 脚本执行,而不是逐行执行,您可以在 GNU make 中执行以下操作:定义.ONESHELL
目标。
define my_important_task =
# script goes here
endef
my-important-task: ; $(value my_important_task)
.ONESHELL:
答案2
https://www.gnu.org/software/make/manual/html_node/One-Shell.html
如果 .ONESHELL 特殊目标出现在 makefile 中的任何位置,则每个目标的所有配方行都将提供给 shell 的单次调用。
您仍然需要在每行的开头放置一个制表符,并将所有美元符号加倍(即在脚本中的所有位置替换)$
。$$
答案3
如果问题是您的顶级项目目录中挤满了数十个脚本,那么显而易见的解决方案是创建一个子目录(例如称为scripts
)来放置它们。
运行它们./scripts/scriptname
和/或将脚本目录添加到您的 PATH 中。
如果您仍然希望使用 Makefile 来运行它们,只需创建./scripts/scriptname
为这些目标运行的 Makefile 条目即可。例如
my-important-task:
./scripts/my-important-task.sh my-parameter
注意:如果 ./scripts 中的脚本调用同一目录中的其他脚本,则它们需要指定脚本的完整路径,或者在 PATH 中包含脚本目录。
答案4
顺便说一句......你不能只使用 Bash。
事实上,您可以使用任何您想要的脚本语言编写 make 目标配方。
使用 Python 的示例片段:
...
SHELL != sh -c "command -v python"
.SHELLFLAGS := -c
.ONESHELL:
# et voilà : the recipe can now be written in pure python :-)
all: foo
# use some make variables
print "# target name is '$@', depends on '$^'"
import os
print os.listdir ("..")
foo:
# use some make variables
print "# target name is '$@', depends on '$^'"
import sys
print 'python version is %s.%s.%s' % (sys.version_info[0], sys.version_info[1], sys.version_info[2])
...
请参阅各种语言的示例:https://github.com/lgersman/make-recipes-in- Different-scripting-languages-demo