我应该如何在Makefile中嵌入python脚本?

2024-04-18 18:00:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在Makefile中嵌入python脚本

我构建了一个python -c脚本(如下),它在我的MacBook Hyper terminal中运行良好:

% 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 CLIpython -c ...命令成功启动MacBook上的Docker desktop

我知道有一些非python的方法可以解决这个特定的问题。。。我需要一个通用的python Makefile解决方案


Tags: todockerfromimportoutputmakeopenall
2条回答

由于Python的缩进要求,在Makefile中使用python -c是很棘手的。一个简单的解决方案是,如果要使用Bash“C-style”字符串,请使用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

如果open失败make将以错误消息终止;从Python打印本质上相同的消息似乎是多余的。如果您想不顾错误继续,您可以这样做

all:
    open  background -a Docker || \
    echo "Docker desktop failed to launch: exit-code: $$?"

。。。尽管我认为Python脚本的失败(sic)只是一个错误

我发现了一种相当简单的方法,可以将多行python脚本嵌入到Makefile

  1. 将此保存为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
  1. 测试输出:
% 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
%
%

相关问题 更多 >