假装成为 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中文网其他相关文章!