shell 如何在我的makefile中提示用户输入[y/n](使用纯make语法)?

bwitn5fc  于 2022-12-13  发布在  Shell
关注(0)|答案(3)|浏览(218)

我正在写一个makefile,它应该在Windows和Linux上都能工作。所以只要有可能,我就避免使用特定于操作系统的shell命令。
下面是我的makefile中的一段代码,结尾是clean函数:

# OS specific part
# -----------------
ifeq ($(OS),Windows_NT)
    RM = del /F /Q
    RMDIR = -RMDIR /S /Q
    MKDIR = -mkdir
    ERRIGNORE = 2>NUL || (exit 0)
    SEP=\\
else
    RM = rm -rf 
    RMDIR = rm -rf 
    MKDIR = mkdir -p
    ERRIGNORE = 2>/dev/null
    SEP=/
endif
PSEP = $(strip $(SEP))

# Definitions for nullstring and space
# -------------------------------------
nullstring :=
space := $(nullstring) #End

# Lists of all files and folders to keep or remove
# -------------------------------------------------
buildFiles_toKeep := ...    # I wrote some scripts to
buildDirs_toKeep := ...     # automatically generate
buildFiles_toRemove := ...  # these lists. But that would lead
buildDirs_toRemove := ...   # us too far here.

.PHONY: clean
clean:
    @echo.
    @echo ----------------------------------------------------------
    @echo.$(space)        __         **************    $(space)
    @echo.$(space)      __\ \___     * make clean *    $(space)
    @echo.$(space)      \ _ _ _ \    **************    $(space)
    @echo.$(space)       \_`_`_`_\                     $(space)
    @echo.$(space)                                     $(space)
    @echo.$(space)Keep these files:
    @echo.$(space)  $(buildFiles_toKeep)
    @echo.$(space)
    @echo $(space)Keep these directories:
    @echo.$(space)  $(buildDirs_toKeep)
    @echo.$(space)
    @echo.$(space)Remove these files:
    @echo.$(space)  $(buildFiles_toRemove)
    $(RM) $(buildFiles_toRemove)
    @echo.
    @echo.$(space)Remove these directories:
    @echo.$(space)  $(buildDirs_toRemove)
    $(RMDIR) $(buildDirs_toRemove)
    @echo.
@echo ----------------------------------------------------------

这个makefile在Windows和Linux上都很好用,它用正确的shell命令替换$(RM)$(RMDIR)来删除文件和文件夹。但是我想提示用户,让他/她可以按Y或N。我不想删除他/她想保留的文件。我试着插入一些批处理-命令插入clean目标的recipees中,提示用户输入。但是提示符没有显示。可能是因为GNU make延迟了输入流。
我想知道是否有可能用'pure' make语法生成一个[Y/N]提示符(没有特定于操作系统的shell命令)。我知道make语言有它的局限性。也许一个聪明的解决方案可以在一个操作系统(如Linux)上工作,并以最小的开销移植到另一个操作系统(如Windows)上。
有人有主意吗?

编辑:

我得到了这个链接:如何让'make'提示用户输入密码并将其存储在Makefile变量中?
Gnu make将通过提示用户创建变量PASSWORD

$ cat Makefile 
PASSWORD ?= $(shell bash -c 'read -s -p "Password: " pwd; echo $$pwd')

这种提示用户输入的方式可以很好地工作,只要你希望提示在你的makefile被解析的时候出现。但是我的情况不同。我想在makefile已经运行的时候提示用户,换句话说,当makefile中的recipees正在执行的时候。

编辑:

当你运行make multi-threaded时,提示用户是不可能的,所以我完全可以调用clean函数single-threaded:

>> make clean -j1

毕竟,clean函数并不需要很长时间就可以完成。我不打算在build函数中提示用户任何内容,这样就可以多线程执行:-)

>> make all -j8 --output-sync=target
xzv2uavs

xzv2uavs1#

从概念上讲,make是一个非常简单的应用程序,它只有一个目的a-构建一个依赖关系树,并重新构建具有更新祖先的东西。交互不应该是一个因素,所以make并不原生地提供它,理想情况下make应该已经拥有了它所需要的所有信息。如果你真的需要,你可以使用shell!=,或者甚至使用guile或load提供您自己扩展。
不过,这并不真正适用于clean规则,因为clean一开始并不重做任何东西,它只是一个快速的技巧,允许您使用make语法方便地表达一个非make操作。
就我个人而言,我看不出提示用户删除文件有什么价值,除非你要删除的东西不是你负责的,这本身就是一个反模式。
如果你非常确定你需要这个,那么就把clean的方法 Package 在一个脚本中,并提供bash和windows的两个版本。你也可以假设任何在windows上运行GNU make的人已经在使用MSYS 2,Cygwin,或者微软认可的bash for Windows 10版本,而完全放弃cmd / powershell脚本。

ua4mk5z4

ua4mk5z42#

如果你想用Yes / No变成一个一行的例子来执行某事(这里是另一个makefile目标):

request-test:
    @echo -n "Are you sure? [y/N] " && read ans && if [ $${ans:-'N'} = 'y' ]; then make ENV=test spec-tests; fi

1.问题将被提示;
1.响应将被读取并存入一个名为ans的变量;

  1. if使用默认值读取ans变量的值以避免错误。
vjhs03f7

vjhs03f73#

生成文件:

sure:
    @echo -n "Are you sure? [Y/n] " && read ans && if [ $${ans:-'Y'} = 'n' ]; then \
        printf $(_ERROR) "KO" "Stopping" ; \
        exit 1 ; \
    else \
        printf $(_SUCCESS) "OK" "Continuing" ; \
        exit 0; \
    fi


_SUCCESS := "\033[32m[%s]\033[0m %s\n" # Green text for "printf"
_ERROR := "\033[31m[%s]\033[0m %s\n" # Red text for "printf"

相关问题