You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GNU Make中printf加cat管道输出异常及与Dash行为差异问题

Makefile中管道命令与直接执行Dash行为不一致的原因

问题场景

Makefile内容:

foo:
    printf '\x41\n'

bar:
    printf '\x41\n' | cat

执行结果:

  • 执行make foo输出A
  • 执行make bar输出\x41

系统默认shell指向Dash:

# ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Sep 12 04:41 /bin/sh -> dash

但直接在Dash终端中执行两条命令,输出均为\x41。


原因解析

  1. GNU Make的命令执行逻辑差异
    GNU Make处理命令时会区分两种情况:

    • 当命令是无shell元字符(管道、分号、重定向等)的单条命令时,Make会直接通过exec系统调用执行该命令,不会启动shell进程。
    • 当命令包含管道、分号等shell元字符时,Make会启动/bin/sh(即Dash),将整个命令串交给shell解析执行。
  2. 不同printf实现的转义支持差异

    • 系统中存在两个printf:一个是GNU printf(来自coreutils包,路径通常为/usr/bin/printf),它支持\x十六进制转义,能把\x41解析为字符A。
    • Dash内置了自己的printf,不支持\x转义,会将\x41原样输出。
  3. 对应场景的具体解释

    • make foo:命令是单条无元字符的printf '\x41\n',Make直接执行/usr/bin/printf,所以输出A。
    • make bar:命令包含管道|,Make启动Dash执行整个命令,此时用的是Dash内置的printf,输出\x41后传给cat,最终显示\x41。
    • 直接在Dash中执行时,无论是否加管道,都会调用Dash内置的printf,所以两条命令都输出\x41。

内容的提问来源于stack exchange,提问作者Lone Learner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 09:41:19