1# pty 2 3Pty is a Go package for using unix pseudo-terminals. 4 5## Install 6 7```sh 8go get github.com/creack/pty 9``` 10 11## Examples 12 13Note that those examples are for demonstration purpose only, to showcase how to use the library. They are not meant to be used in any kind of production environment. 14 15### Command 16 17```go 18package main 19 20import ( 21 "io" 22 "os" 23 "os/exec" 24 25 "github.com/creack/pty" 26) 27 28func main() { 29 c := exec.Command("grep", "--color=auto", "bar") 30 f, err := pty.Start(c) 31 if err != nil { 32 panic(err) 33 } 34 35 go func() { 36 f.Write([]byte("foo\n")) 37 f.Write([]byte("bar\n")) 38 f.Write([]byte("baz\n")) 39 f.Write([]byte{4}) // EOT 40 }() 41 io.Copy(os.Stdout, f) 42} 43``` 44 45### Shell 46 47```go 48package main 49 50import ( 51 "io" 52 "log" 53 "os" 54 "os/exec" 55 "os/signal" 56 "syscall" 57 58 "github.com/creack/pty" 59 "golang.org/x/term" 60) 61 62func test() error { 63 // Create arbitrary command. 64 c := exec.Command("bash") 65 66 // Start the command with a pty. 67 ptmx, err := pty.Start(c) 68 if err != nil { 69 return err 70 } 71 // Make sure to close the pty at the end. 72 defer func() { _ = ptmx.Close() }() // Best effort. 73 74 // Handle pty size. 75 ch := make(chan os.Signal, 1) 76 signal.Notify(ch, syscall.SIGWINCH) 77 go func() { 78 for range ch { 79 if err := pty.InheritSize(os.Stdin, ptmx); err != nil { 80 log.Printf("error resizing pty: %s", err) 81 } 82 } 83 }() 84 ch <- syscall.SIGWINCH // Initial resize. 85 defer func() { signal.Stop(ch); close(ch) }() // Cleanup signals when done. 86 87 // Set stdin in raw mode. 88 oldState, err := term.MakeRaw(int(os.Stdin.Fd())) 89 if err != nil { 90 panic(err) 91 } 92 defer func() { _ = term.Restore(int(os.Stdin.Fd()), oldState) }() // Best effort. 93 94 // Copy stdin to the pty and the pty to stdout. 95 // NOTE: The goroutine will keep reading until the next keystroke before returning. 96 go func() { _, _ = io.Copy(ptmx, os.Stdin) }() 97 _, _ = io.Copy(os.Stdout, ptmx) 98 99 return nil 100} 101 102func main() { 103 if err := test(); err != nil { 104 log.Fatal(err) 105 } 106} 107``` 108