如果未定义,如何提示目标特定的Makefile变量?

6

这与另一个问题类似,但我希望只有当运行了特定的目标且未指定强制变量时,make才提示输入值。

当前的代码:

install-crontab: PASSWORD ?= "$(shell read -p "Password: "; echo "$$REPLY")"
install-crontab: $(SCRIPT_PATH)
    @echo "@midnight \"$(SCRIPT_PATH)\" [...] \"$(PASSWORD)\""

这只会输出以下内容,没有提示:
Password: read: 1: arg count
@midnight [...] ""

这里的重要点是我只需要在运行此目标时询问,并且仅当变量未定义时才需要。不能使用configure脚本,因为显然不应将密码存储在配置脚本中,并且此目标不是标准安装过程的一部分。

2个回答

6
原来问题在于Makefile不使用Dash / Bash风格的引号,并且Dash的read内置需要变量名,与Bash不同。修改后的代码如下:
install-crontab-delicious: $(DELICIOUS_TARGET_PATH)
    @while [ -z "$$DELICIOUS_USER" ]; do \
        read -r -p "Delicious user name: " DELICIOUS_USER;\
    done && \
    while [ -z "$$DELICIOUS_PASSWORD" ]; do \
        read -r -p "Delicious password: " DELICIOUS_PASSWORD; \
    done && \
    while [ -z "$$DELICIOUS_PATH" ]; do \
        read -r -p "Delicious backup path: " DELICIOUS_PATH; \
    done && \
    ( \
        CRONTAB_NOHEADER=Y crontab -l || true; \
        printf '%s' \
            '@midnight ' \
            '"$(DELICIOUS_TARGET_PATH)" ' \
            "\"$$DELICIOUS_USER\" " \
            "\"$$DELICIOUS_PASSWORD\" " \
            "\"$$DELICIOUS_PATH\""; \
        printf '\n') | crontab -

结果:

$ crontab -r; make install-crontab-delicious && crontab -l
Delicious user name: a\b c\d
Delicious password: e f g
Delicious backup path: h\ i
no crontab for <user>
@midnight "/usr/local/bin/export_Delicious" "a\b c\d" "e f g" "h\ i"
$ DELICIOUS_PASSWORD=foo make install-crontab-delicious && crontab -l
Delicious user name: bar
Delicious backup path: baz
@midnight "/usr/local/bin/export_Delicious" "a\b c\d" "e f g" "h\ i"
@midnight "/usr/local/bin/export_Delicious" "bar" "foo" "baz"

这段代码:

  • 把所有输入字符都视作字面量,因此可以处理空格和反斜杠符号,
  • 避免了用户未写任何内容就按下 Enter 键的问题,
  • 使用环境变量(如果存在),并且
  • 无论 crontab 是否为空都可以正常工作。

2

l0b0的回答帮助了我解决了一个类似的问题,当用户没有输入“y”时,我想要退出。最终我做了这个:

@while [ -z "$$CONTINUE" ]; do \
    read -r -p "Type anything but Y or y to exit. [y/N] " CONTINUE; \
done ; \
if [ ! $$CONTINUE == "y" ]; then \
if [ ! $$CONTINUE == "Y" ]; then \
    echo "Exiting." ; exit 1 ; \
fi \
fi

希望这有助于某些人。使用用户输入进行makefile中的if / else的更多信息很难找到。


除非我眼花,否则这个 while 循环会重复而不是使用默认的 N,如果你只是按下回车键。 - l0b0
你应该在条件语句中使用单个等号=。参考链接:http://mywiki.wooledge.org/Bashism#Conditionals - l0b0
2
您还可以简化 if 语句:if [ $$CONTINUE != "y" ] && [ $$CONTINUE != "Y" ]; then。或者使用 [ $$CONTINUE = "y" ] || [ $$CONTINUE = "Y" ] || (echo "退出中."; exit 1;) 更简洁。 - l0b0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接