首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >戈朗终端: syscall vs os/exec stty

戈朗终端: syscall vs os/exec stty
EN

Stack Overflow用户
提问于 2018-06-22 10:45:30
回答 2查看 1.9K关注 0票数 4

以下是使用syscall在go中获得(POSIX)终端大小的方法:

代码语言:javascript
复制
func getTermDim() (width, height int, err error) {
    var termDim [4]uint16
    if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(0), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&termDim)), 0, 0, 0); err != 0 {
        return -1, -1, err
    }
    return int(termDim[1]), int(termDim[0]), nil
}

现在,同样的事情,使用os/exec调用stty:

代码语言:javascript
复制
func getTermDim() (width, height int, err error) {
        cmd := exec.Command("stty", "size")
        cmd.Stdin = os.Stdin
        var termDim []byte
        if termDim, err = cmd.Output(); err != nil {
                return
        }
        fmt.Sscan(string(termDim), &height, &width)
        return
}

在实践中,第一种解决方案可能会变得非常沉重和不可读,当您必须将终端置于原始模式、设置选项等时,当您习惯使用stty (例如在shell脚本中)时,第二种解决方案就容易得多了!

所以我的问题是:使用第一个解决方案有什么好处?是速度吗?我们不能依赖stty命令安装在主机上吗?还有什么我想不起来的?

简而言之,使用stty对syscall的“风险”或“成本”是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-12-01 09:44:02

关于风险:

  • stty:如果stty命令在$PATH中不可用,您的程序将无法正常工作。或者如果stty命令在$PATH中不是您所期望的(这可能是一个安全问题)。或者,如果程序运行在具有极简主义足迹的Docker容器中,则必须将stty放在映像中。
  • syscall:您的程序依赖于操作系统。只要您将该函数写入受构建标签保护的文件中,以确保在不受支持的操作系统上编译时生成将失败,就可以了。

关于性能,只需使用包基准测试编写testing即可。但我已经可以告诉您,exec.Command意味着比IOCTL/TIOCGWINSZ更昂贵的多个系统。

票数 1
EN

Stack Overflow用户

发布于 2022-09-28 18:45:40

很可能,如果盒子上存在stty,那么syscall也会出现。似乎它和论点TIOCGWINSZ都是SVR4标准的一部分,这个标准可以追溯到20年前,并且在任何地方都是由Unixes广泛实现的,所以您不太可能需要针对不同OSes的变体代码,ioctl也是可移植的。

当然,运行stty更容易读懂,但是您正在运行一个单独的进程,这需要付出一定的代价。

它速度更慢,成本更高:操作系统正在启动一个新的进程上下文并加载二进制文件;您的代码不仅生成多个系统,而且运行的进程也是如此。

它还伴随着一系列的安全问题。也许您在path上找到的stty是用户放置在其中的一个,这只是一个例子;如果您嵌入了一个路径,那么对于这个特定的操作系统来说可能是错误的)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50986225

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档