我运行的程序中的一些目标Makefile,其输出(它们发送到stdout)是我感兴趣的。由于我不知道的原因, 的作者make决定将执行的命令回显到stdout,这会污染后者。
这里建议了一种解决此问题的硬方法,其中涉及交换文件描述符。我想知道是否有一种更简单的方法来强制makeecho 到stderr.
我浏览了man的页面make,但除了选项之外没有找到任何与此目的相关的内容-s。我更喜欢保留命令的回显,但将其放在stderr.
我还尝试创建一个辅助目标(我将其作为所有其他目标的先决条件),我在其中放置了:
exec 3>&2
exec 2>&1
exec 1>&3
Run Code Online (Sandbox Code Playgroud)
但 bash 抱怨 3 不是有效的文件描述符。我只是尝试过exec 1>&2,但没有任何效果......
make 在 stdout 上显示命令行的原因是因为这是 make 的 POSIX 标准所要求的,也是 30 多年历史所期望的。请参阅http://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html并搜索有关“STDOUT”的部分。
您无法从配方中修改 make 程序中的文件描述符,因为配方在子 shell 中运行:对文件描述符所做的任何更改仅在子 shell 中生效。在 UNIX 中,子进程不可能修改其父进程的文件描述符。
类似地,make 中配方中的每一行都在不同的子 shell中运行。如果你想做一些奇特的事情,比如重定向食谱的输出,你必须将其全部写在一行上:
exec 3>&2; exec 2>&1; exec 1>&3; <my command here>
Run Code Online (Sandbox Code Playgroud)
当然,如果您打算经常这样做,我会将其放入 make 变量中并使用该变量。
没有办法让 make 将其输出写入 stderr 而不是 stdout,除非您想修改 GNU make 的源代码并使用您自己构建的版本。实际上,只要您使用较新版本的 GNU make(4.0 及更高版本),执行此操作就很简单,因为所有输出都是从一个 plase 生成的(在output.c)。