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

如何通过GoLang程序化禁用Mac终端的回显功能

解决Mac/Windows终端用Go禁用回显的问题

我来帮你搞定这个在Mac和Windows终端禁用回显的问题,先从你遇到的Mac手动执行命令无效的情况说起,再给你跨平台的Go实现方案:

Mac终端手动执行stty无效的解决办法

你之前在bash/zsh里直接跑stty -echo没生效,大概率是因为Mac的stty需要明确指定终端设备路径,并且参数是小写的-f(而不是Linux的-F)。试试执行这条命令:

stty -f /dev/tty -echo

执行后你输入内容就不会回显了,要恢复正常回显的话,执行:

stty -f /dev/tty echo

跨平台Go代码实现禁用回显

因为不同系统的终端控制方式不一样,我们需要针对Linux、Mac、Windows分别处理:

1. Mac/Linux平台的Go代码

通过runtime.GOOS判断系统,调用对应参数的stty命令,同时一定要记得恢复回显(避免终端一直处于无回显状态):

package main

import (
	"fmt"
	"os/exec"
	"runtime"
)

// 禁用回显
func disableEcho() error {
	var cmd *exec.Cmd
	switch runtime.GOOS {
	case "linux":
		cmd = exec.Command("stty", "-F", "/dev/tty", "-echo")
	case "darwin": // Mac系统
		cmd = exec.Command("stty", "-f", "/dev/tty", "-echo")
	default:
		return fmt.Errorf("当前系统暂不支持")
	}
	return cmd.Run()
}

// 恢复回显
func enableEcho() error {
	var cmd *exec.Cmd
	switch runtime.GOOS {
	case "linux":
		cmd = exec.Command("stty", "-F", "/dev/tty", "echo")
	case "darwin":
		cmd = exec.Command("stty", "-f", "/dev/tty", "echo")
	default:
		return fmt.Errorf("当前系统暂不支持")
	}
	return cmd.Run()
}

func main() {
	// 禁用回显,程序退出前恢复
	err := disableEcho()
	if err != nil {
		fmt.Printf("禁用回显失败: %v\n", err)
		return
	}
	defer enableEcho()

	// 这里可以写需要无回显的逻辑,比如读取密码
	fmt.Println("请输入密码(无回显):")
	var password string
	fmt.Scanln(&password)
	fmt.Printf("你输入的密码是:%s\n", password)
}

2. Windows平台的Go代码

Windows没有stty命令,需要调用Windows API修改控制台模式。下面是实现代码:

package main

import (
	"fmt"
	"syscall"
	"unsafe"
)

var (
	kernel32       = syscall.NewLazyDLL("kernel32.dll")
	getConsoleMode = kernel32.NewProc("GetConsoleMode")
	setConsoleMode = kernel32.NewProc("SetConsoleMode")
)

// 禁用回显,返回原来的控制台模式用于恢复
func disableEcho() (uint32, error) {
	var mode uint32
	handle, err := syscall.GetStdHandle(syscall.STD_INPUT_HANDLE)
	if err != nil {
		return 0, err
	}

	// 获取当前控制台模式
	ret, _, err := getConsoleMode.Call(uintptr(handle), uintptr(unsafe.Pointer(&mode)))
	if ret == 0 {
		return 0, err
	}
	originalMode := mode
	// 移除回显标志位(ENABLE_ECHO_INPUT = 0x0004)
	mode &^= 0x0004
	// 设置新的控制台模式
	ret, _, err = setConsoleMode.Call(uintptr(handle), uintptr(mode))
	if ret == 0 {
		return 0, err
	}
	return originalMode, nil
}

// 根据原来的模式恢复回显
func enableEcho(originalMode uint32) error {
	handle, err := syscall.GetStdHandle(syscall.STD_INPUT_HANDLE)
	if err != nil {
		return err
	}
	ret, _, err := setConsoleMode.Call(uintptr(handle), uintptr(originalMode))
	if ret == 0 {
		return err
	}
	return nil
}

func main() {
	originalMode, err := disableEcho()
	if err != nil {
		fmt.Printf("禁用回显失败: %v\n", err)
		return
	}
	defer enableEcho(originalMode)

	fmt.Println("请输入密码(无回显):")
	var password string
	fmt.Scanln(&password)
	fmt.Printf("你输入的密码是:%s\n", password)
}

小提示

  • 如果用终端模拟器(比如iTerm2),确保没有在终端设置里强制开启回显,不过默认不会有这个问题。
  • 不管哪种平台,一定要用defer保证程序退出前恢复回显,不然终端会一直处于无回显状态,手动执行stty echo(Mac/Linux)也能恢复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:14:44