我想将
python
脚本嵌入到 Makefile
中
我构建了一个
python -c
脚本(如下),它在我的 MacBook 中运行良好超级终端:
% python -c $'from subprocess import getstatusoutput\noutput=getstatusoutput("open --background -a Docker")\nif int(output[0])>0:\n print("Docker desktop failed to launch: exit-code:{}".format(output[0]))'
由于我还不明白的原因,如果我用它构建一个 Makefile,这似乎会失败(注意:制表符是四个空格......我在 Makefile 中使用了制表符缩进)。
all:
$(shell python -c $'from subprocess import getstatusoutput\noutput=getstatusoutput("open --background -a Docker")\nif int(output[0])>0:\n print("Docker desktop failed to launch: exit-code:{}".format(output[0]))')
运行
make all
目标...
% make all
/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `python -c from subprocess import getstatusoutput\noutput=getstatusoutput("open --background -a Docker")\nif int(output[0])>0:\n print("Docker desktop failed to launch: exit-code:{}".format(output[0]))''
make: `all' is up to date.
%
我已经为此苦苦挣扎了一段时间......
有人可以帮助解释为什么
make all
失败以及修复此 python -c
命令的最佳方法吗? 我的 shell CLI python -c ...
命令成功在我的 MacBook 上启动 Docker 桌面。
我知道有非Python方法可以解决这个特定问题...我需要一个通用的Python Makefile解决方案。
由于 Python 的缩进要求,在
python -c
中使用 Makefile
很棘手。如果您想使用 Bash“C 风格”字符串,一个简单的解决方案是使用 SHELL=/bin/bash
:
SHELL=/bin/bash
all:
# python command must be wrapped in single quotes _and_ have double dollar sign in front
python -c $$'from subprocess import getstatusoutput\noutput=getstatusoutput("open --background -a Docker")\nif int(output[0])>0:\n print("Docker desktop failed to launch: exit-code:{}".format(output[0]))'
(注意美元符号需要加倍才能转义。显然,这限制了
Makefile
到支持 Bash 的系统的可移植性。$'...'
语法允许您使用像 \n
和 这样的转义码\t
在字符串中,并分别将它们扩展为换行符和制表符。此构造特别需要在字符串周围使用前导美元符号和单引号 - 只是 '...'
的作用略有不同,而 $"..."
的作用则完全。不同。)
您还可以 define
make
多行变量。但在这个孤立的案例中,Python 无论如何都没有发挥任何有用的作用。
all:
open --background -a Docker
如果
make
失败,
open
将终止并显示错误消息;从 Python 中打印本质上相同的消息似乎是多余的。如果您想在出现错误的情况下继续,您可以这样做
all:
open --background -a Docker || \
echo "Docker desktop failed to launch: exit-code: $$?"
...虽然我认为 Python 脚本失败(原文如此)只是一个错误。
Makefile
...
Makefile
...
define MULTILINE_PYTHON_SCRIPT
###########################################
# Start multiline python string here...
###########################################
from subprocess import getstatusoutput as gso
print("Here we go:")
for hello_int in [1, 2, 3,]:
print(' Hello World %i' % hello_int)
retval, _ = gso("ls -la")
assert retval==0, "ls command execution failed"
###########################################
# End of multiline python string...
###########################################
endef
export MULTILINE_PYTHON_SCRIPT
EMBEDDED_PY := python -c "$$MULTILINE_PYTHON_SCRIPT"
.PHONY: nothing
nothing:
echo "raw makefile command"
.PHONY: test
test:
$(EMBEDDED_PY)
.PHONY: all
all:
open --background -a Docker
% make nothing
echo "raw makefile command"
raw makefile command
%
% make test
python -c "$MULTILINE_PYTHON_SCRIPT"
Here we go:
Hello World 1
Hello World 2
Hello World 3
%
%