Makefile中如何将stderr重定向并通过fold格式化后写入文件,同时保留原执行逻辑?
实现方法
要在保留原有功能的基础上,用fold命令格式化stderr输出到80字符宽度,你需要调整stderr的重定向逻辑,同时确保能正确捕获原程序的退出状态(用来决定调用successCommand还是failureCommand)。下面是修改后的Makefile代码:
# 如果你的系统默认shell不支持进程替换,需要添加这行指定bash SHELL := /bin/bash define func ./myProgram 2> >(fold -w 80 > error.log); \ exit_code=$$?; \ if [ $$exit_code -eq 0 ]; then \ $(call successCommand); \ else \ $(call failureCommand); \ fi endef
关键细节解释:
- 进程替换
2> >(fold -w 80 > error.log):这部分把myProgram的stderr(文件描述符2)重定向到一个临时管道,管道的输出传给fold -w 80(限制每行80字符),最后格式化后的内容写入error.log。这种方式不会丢失原程序的退出状态。 - 捕获退出码
exit_code=$$?:$$?是shell里获取上一个命令退出状态的变量,在Makefile里需要用两个$转义(避免被Make解析)。我们显式保存这个值,用来判断后续执行哪个命令。 - 显式条件判断:原来的
&&/||在管道场景下会被最后一个命令(fold)的退出状态影响,改用显式判断原程序的退出码更可靠,确保逻辑和你原来的需求一致。
如果你的环境不支持bash的进程替换,也可以用临时文件中转的方式(兼容性更好,但稍显繁琐):
define func ./myProgram 2> temp_stderr.log; \ exit_code=$$?; \ fold -w 80 temp_stderr.log > error.log; \ rm temp_stderr.log; \ if [ $$exit_code -eq 0 ]; then \ $(call successCommand); \ else \ $(call failureCommand); \ fi endef
这种方法先把原始stderr存到临时文件,格式化后再写入目标日志,最后删除临时文件,同样能保留原程序的退出状态。
内容的提问来源于stack exchange,提问作者spaL
相关产品推荐
相关产品推荐

