
在 Go 中捕获 Ctrl+C(SIGINT)时,终端默认会回显 ^C,可通过输出回车符 \r 覆盖该提示,实现干净退出。
在 Go 中捕获 `Ctrl+C`(`SIGINT`)时,终端默认会回显 `^C`,可通过输出回车符 `\r` 覆盖该提示,实现干净退出。
当用户在终端按下 Ctrl+C 时,操作系统不仅向进程发送 SIGINT 信号,还会由终端驱动(如 tty)直接在当前行输出可视提示 ^C —— 这一行为与 Go 程序本身无关,而是终端的本地回显(echo)特性所致。因此,仅靠 signal.Notify 捕获信号无法抑制该显示。
最轻量、兼容性最佳的解决方案是在接收到中断信号后,立即向标准输出写入一个回车符 \r,将光标移至行首,再输出自定义退出信息,从而覆盖掉 ^C:
package main
import (
"fmt"
"log"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
// 启动信号监听
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
// 模拟主程序运行
log.Println("Server started. Press Ctrl+C to exit.")
select {
case <p>⚠️ 注意事项:</p>
- \r 仅将光标移至当前行开头,不换行;若 ^C 出现在行末且前有其他输出,确保后续内容长度 ≥ ^C 占位(通常 2 字符),否则可能残留部分字符;
- 此方法依赖终端支持回车控制,适用于绝大多数现代终端(Linux/macOS Terminal、iTerm2、Windows Terminal、WSL),但不适用于某些精简环境(如部分串口终端或禁用 ICRNL 的 stty 设置);
- 如需彻底禁用 ^C 显示,可临时关闭终端回显(例如用 golang.org/x/term 设置 Raw 模式),但这会同时禁用所有输入回显(包括密码、命令等),适用场景有限,不推荐用于常规 CLI 应用。
综上,fmt.Print("\r") 是平衡简洁性、可移植性与用户体验的最佳实践 —— 它无需外部依赖、零侵入,且能立竿见影地提升终端交互的专业感。











