如何在Makefile中正确实现读取单个用户输入字符?
核心结论
GNU Make 本身没有自带独立版本的read命令,你遇到的报错和Make版本无关,根源是调用的shell不同。
报错原因
Ubuntu 系统中GNU Make默认调用的shell是/bin/sh,而Ubuntu的/bin/sh默认链接到轻量级的POSIX shell实现dash,不是你日常交互使用的bash:
dash内置的read命令不支持非POSIX标准的-n参数,因此直接抛出Illegal option -n错误- 你在终端直接测试时用的是
bash,其内置read对-n参数做了扩展支持,因此运行正常
解决方案
方案1:显式指定Make使用bash执行命令
在Makefile开头新增一行声明即可,后续所有规则中的命令都会用bash执行,兼容read -n写法:
# 放在Makefile最开头 SHELL := /bin/bash all: read -n 1 mychar; echo 'you typed '$$mychar
方案2:使用全POSIX兼容的单字符读取写法
如果要保证Makefile的跨发行版兼容性,不想依赖bash,可以用dd命令实现单字符读取,兼容所有符合POSIX标准的shell:
all: mychar=$$(dd bs=1 count=1 2>/dev/null); echo 'you typed '$$mychar
Make与shell环境的关系说明
你关注的make与shell的关联逻辑如下:
- Make执行规则中的命令时,每一行命令都会启动一个独立的shell子进程执行,默认使用的shell路径由Make编译时的配置决定,Debian/Ubuntu系发行版默认都配置为
/bin/sh - 除了手动在Makefile中设置
SHELL变量外,Make不会默认继承当前终端的shell配置,即使你当前终端用的是bash,Make还是会按默认配置调用/bin/sh - 所有shell内置命令的行为完全由实际调用的shell实现决定,和Make本身功能无关
内容的提问来源于stack exchange,提问作者Chiarcos
相关产品推荐
相关产品推荐

