管道:运行 make 命令时错误的文件描述符

时间:2021-07-29 10:16:43

标签: python makefile

有人可以帮我解决这个问题吗? 我正在尝试运行一个应用程序,每当我在终端中运行 ma​​ke 时,我都会遇到该错误

process_begin: CreateProcess(NULL, python3.8 -c "import sys; print(sys.version_info[:2] >= (3, 8))", ...) failed.enter code here
Makefile:24: pipe: Bad file descriptor

SETUP  Creating virtualenv

FATAL  Python not found (python3.8)

make: *** [Makefile:21: .venv] Error 1

我在运行和安装 python8.3 之前创建了一个 venv,还有 pip。

生成文件

PYTHON ?= python3.8
FLASK_HOST ?= 127.0.0.1
FLASK_PORT ?= 5000
VENV ?= .venv

SHELL := /bin/bash
PIP := ${VENV}/Scripts/pip
FLASK := ${VENV}/Scripts/flask
CONFIG := licmon/licmon.cfg
SERVERS := licmon/servers.cfg

.PHONY: all
all: ${VENV} config
    @printf "\033[38;5;154mSETUP\033[0m  \033[38;5;105mInstalling licmon python package\033[0m\n"
    @${PIP} install -q -e '.[dev]'

 
${VENV}:
    @printf "\033[38;5;154mSETUP\033[0m  \033[38;5;105mCreating virtualenv\033[0m\n"
ifeq (, $(shell which ${PYTHON} 2> /dev/null))
    @printf "\033[38;5;220mFATAL\033[0m  \033[38;5;196mPython not found (${PYTHON})\033[0m\n"
    @exit 1
endif
ifneq (True, $(shell ${PYTHON} -c 'import sys; print(sys.version_info[:2] >= (3, 8))'))
    @printf "\033[38;5;220mFATAL\033[0m  \033[38;5;196mYou need at least Python 3.8\033[0m\n"
    @exit 1
endif
    @${PYTHON} -m venv --prompt licmon .venv
    @${PIP} install -q -U pip setuptools


${CONFIG}: | ${CONFIG}.example
    @printf "\033[38;5;154mSETUP\033[0m  \033[38;5;105mCreating config [\033[38;5;147m${CONFIG}\033[38;5;105m]\033[0m\n"
    @cp ${CONFIG}.example ${CONFIG}
    @printf "\033[38;5;154mSETUP\033[0m  \033[38;5;105mCreating config [\033[38;5;147m${SERVERS}\033[38;5;105m]\033[0m\n"
    @cp ${SERVERS}.example ${SERVERS}
    @sed -i.bak "s/^SECRET_KEY = None/SECRET_KEY = '$$(LC_ALL=C tr -dc A-Za-z0-9 < /dev/urandom | head -c 32)'/" ${CONFIG}
    @sed -i.bak "s/^SKIP_LOGIN = False/SKIP_LOGIN = True/" ${CONFIG}
    @sed -i.bak "s/^EMAIL_BACKEND = '[^']\+'/EMAIL_BACKEND = 'licmon.vendor.django_mail.backends.console.EmailBackend'/" ${CONFIG}
    @rm -f ${CONFIG}.bak
    @printf "       \033[38;5;82mDon't forget to update the config files if needed!\033[0m\n"


.PHONY: flask-server
flask-server:
    @printf "  \033[38;5;154mRUN\033[0m  \033[38;5;75mRunning Flask dev server [\033[38;5;81m${FLASK_HOST}\033[38;5;75m:\033[38;5;81m${FLASK_PORT}\033[38;5;75m]\033[0m\n"
    @${FLASK} run -h ${FLASK_HOST} -p ${FLASK_PORT} --extra-files $(abspath licmon/licmon.cfg):$(abspath licmon/servers.cfg)


.PHONY: build
build:
    @printf "  \033[38;5;154mBUILD\033[0m  \033[38;5;176mBuilding production package\033[0m\n"
    @rm -rf build
    @source ${VENV}/bin/activate
    @${PIP} list
    @python setup.py bdist_wheel -q


.PHONY: config
config: ${CONFIG}


.PHONY: clean
clean:
    @printf "\033[38;5;154mCLEAN\033[0m  \033[38;5;202mDeleting all generated files...\033[0m\n"
    @rm -rf .venv newdle.egg-info pip-wheel-metadata dist build
    @find newdle/ -name __pycache__ -exec rm -rf {} +
    


1 个答案:

答案 0 :(得分:0)

在您确定makefile 正常工作之前,切勿使用@ 来抑制回显makefile 命令。即便如此,请考虑不这样做。

此外,我敦促您避免将 ANSI 转义序列放入您的 makefile 中。它们读起来令人讨厌,并且它们不会在所有情况下都有效。从您在此处提供的任何 makefile 中绝对省略它们,因为它们不是任何最小可重现示例的一部分,除非它专门询问它们。

反正这个问题...

<块引用>
process_begin: CreateProcess(NULL, python3.8 -c "import sys; print(sys.version_info[:2] >= (3, 8))", ...) failed.enter code here
Makefile:24: pipe: Bad file descriptor

...似乎是这个问题的结果...

<块引用>
FATAL  Python not found (python3.8)

。消息在输出中以这种方式排序,因为这是它们生成的顺序,反映了您方法中的一个严重缺陷。

GNU make 指令,例如 ifeq,在解析 makefile 时,在运行任何配方之前进行评估。因此,这段代码...

<块引用>
ifeq (, $(shell which ${PYTHON} 2> /dev/null))
    @printf "\033[38;5;220mFATAL\033[0m  \033[38;5;196mPython not found (${PYTHON})\033[0m\n"
    @exit 1
endif

... 如果未找到请求的 Python 解释器,则不会立即停止构建。 exit 命令是配方的一部分,它(尚未)运行。因此,make 继续评估下一个指令:

<块引用>
ifneq (True, $(shell ${PYTHON} -c 'import sys; print(sys.version_info[:2] >= (3, 8))'))

。如果确实没有找到 ${PYTHON},那么正在执行的 shell 命令将失败并报告错误,但是,在 $(shell) 函数的执行中发生的情况不会终止构建。 Make 决定构建 ${VENV} 目标,并且在执行该目标的配方时,它最终开始打印“FATAL”消息并执行由上述 @exit 1 保护的 ifeq。这会导致 make 停止构建并报告 .venv (== ${VENV}) 的配方有错误。

<块引用>

我在运行和安装 python8.3 之前创建了一个 venv,还有 pip。

无论可能安装或未安装什么软件,任何 shell make 用于执行 $(shell) 函数(它还将用于执行配方)都没有命令 {{1}在其可执行搜索路径中。提供的信息不足,无法进一步解决此问题。

此外,python3.8 在其工作目录中没有看到子目录 make,否则它不会执行 .venv 目标的配方。如果这让您感到惊讶,那么它可能是从错误的工作目录中运行 .venv 造成的。关于这一点也不能多说。


总的来说,我认为您太努力了,至少在 make 方面是这样。如果需要,我只会让 make 在配方中的执行失败,not 抑制命令回显。生成文件会更容易编写,诊断输出也更容易解释。

相关问题