首页 >后端开发 >Golang >如何让我的程序在 Linux 和 macOS 中伪装成 TTY?

如何让我的程序在 Linux 和 macOS 中伪装成 TTY?

Linda Hamilton
Linda Hamilton原创
2024-12-14 06:11:11719浏览

How Can I Make My Program Pretend to Be a TTY in Linux and macOS?

假装成为 TTY:深入研究

编程中遇到的常见挑战之一是处理歧视输入源的程序(如 stdin)基于它们是终端 (TTY) 还是管道。为了解决这个问题,您可能需要让您的程序假装成 TTY。在本文中,我们将探讨如何使用独立的二进制程序在 Linux 和 macOS 中实现这一目标,主要关注 Go。

假装成 TTY 的关键思想是创建一个伪终端(也称为伪终端)。称为 pty)。 pty 是一个虚拟终端,其行为类似于常规终端,但它实际上是作为一对文件描述符实现的。这些文件描述符之一用于从 pty 读取输入,而另一个用于将输出写入其中。

以下 Go 代码提供了如何创建 pty 并在其中运行命令的示例,捕获其输出:

package main

import (
    "io"
    "log"
    "os"
    "os/exec"
    "runtime"
)

func main() {
    // Get the current operating system.
    osName := runtime.GOOS

    // Create a master pty.
    master, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0)
    if err != nil {
        log.Fatal(err)
    }

    // Get the slave pty name.
    slaveName, err := ptsname(master)
    if err != nil {
        log.Fatal(err)
    }

    // Fork a child process.
    child, err := os.ForkExec("/bin/sh", []string{"sh", "-c", "ls -la"}, nil, slaveName, master, master)
    if err != nil {
        log.Fatal(err)
    }

    // Close the master pty.
    master.Close()

    // Read output from the slave pty.
    buf := make([]byte, 1024)
    for {
        n, err := os.Read(child, buf)
        if err == io.EOF {
            break
        }
        if err != nil {
            log.Fatal(err)
        }
        if osName == "linux" {
            // Remove carriage return (CR) characters.
            buf = buf[:n-1]
        }
        os.Stdout.Write(buf)
    }

    // Wait for the child process to exit.
    child.Wait()
}

可以使用以下命令将此代码编译为独立的二进制文件:

go build -o ttypretend main.go

一次编译完成后,可以按如下方式运行程序:

./ttypretend

并且会输出当前目录的内容。

以上是如何让我的程序在 Linux 和 macOS 中伪装成 TTY?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn