printk()是否已被弃用?为何调用后dmesg仅输出空行?
printk没被弃用,问题出在你的调用语法上
核心结论
printk完全没被弃用,你遇到的dmesg空行问题,纯粹是printk的调用写法错了。
错误原因
你写的代码是:
printk(KERN_ERR, "Hello, world!\n");
这不对。printk的规则是:第一个参数必须是带日志级别的格式字符串——KERN_ERR本身是个字符串宏(比如定义成"<3>"),得和你的消息字符串直接拼在一起,不能用逗号分开。正确写法是:
printk(KERN_ERR "Hello, world!\n");
编译器会自动把这两个相邻的字符串合并成一个,这样printk才能正确识别日志级别,同时输出你的消息。
你之前的错误写法里,printk会把KERN_ERR当成格式字符串,而后面的"Hello..."是多余的参数,但KERN_ERR里没有%s这类占位符,所以只会输出日志级别的前缀(比如<3>),没有实际消息内容,看起来就像空行。
为什么pr_err能用
pr_err()是内核给的封装宏,它已经帮你把KERN_ERR和格式字符串的拼接做好了,定义大概是这样:
#define pr_err(fmt, ...) printk(KERN_ERR fmt, ##__VA_ARGS__)
所以你调用pr_err("Hello, world!\n")的时候,相当于自动帮你补全了正确的printk写法,自然能正常输出。
补充说明
- printk至今还是内核最基础的日志函数,根本没被弃用,
pr_info、pr_err这些宏只是为了让你写代码更省事,不用手动拼日志级别而已。 - 以后用printk的时候,记住:日志级别宏和消息字符串之间直接连起来,别加逗号。
内容的提问来源于stack exchange,提问作者Marco Montevechi Filho
相关产品推荐
相关产品推荐

