TTY のふりをする: より深く掘り下げる
プログラミングで遭遇する一般的な課題の 1 つは、入力ソースを区別するプログラムに対処することです。 (標準入力と同様) 端末 (TTY) であるかパイプであるかに基づきます。これに対処するには、プログラムに TTY のふりをさせる必要がある場合があります。この記事では、主に Go に焦点を当て、スタンドアロンのバイナリ プログラムを使用して Linux と macOS の両方でこれを実現する方法を検討します。
TTY のふりをする背後にある重要なアイデアは、疑似端末 (また、 ptyとして知られています)。 pty は通常の端末のように動作する仮想端末ですが、実際には 1 対のファイル記述子として実装されます。これらのファイル記述子の 1 つは pty から入力を読み取るために使用され、もう 1 つは 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() }
このコードは、次を使用してスタンドアロン バイナリにコンパイルできます。 command:
go build -o ttypretend main.go
コンパイルしたら、次のようにプログラムを実行できます:
./ttypretend
現在のディレクトリの内容が出力されます。
以上がLinux および macOS でプログラムを TTY のように見せかけるにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。