周玉环 d906a41c2e first commit vor 2 Tagen
..
.gitignore d906a41c2e first commit vor 2 Tagen
Dockerfile.golang d906a41c2e first commit vor 2 Tagen
Dockerfile.riscv d906a41c2e first commit vor 2 Tagen
LICENSE d906a41c2e first commit vor 2 Tagen
README.md d906a41c2e first commit vor 2 Tagen
asm_solaris_amd64.s d906a41c2e first commit vor 2 Tagen
doc.go d906a41c2e first commit vor 2 Tagen
ioctl.go d906a41c2e first commit vor 2 Tagen
ioctl_bsd.go d906a41c2e first commit vor 2 Tagen
ioctl_solaris.go d906a41c2e first commit vor 2 Tagen
ioctl_unsupported.go d906a41c2e first commit vor 2 Tagen
mktypes.bash d906a41c2e first commit vor 2 Tagen
pty_darwin.go d906a41c2e first commit vor 2 Tagen
pty_dragonfly.go d906a41c2e first commit vor 2 Tagen
pty_freebsd.go d906a41c2e first commit vor 2 Tagen
pty_linux.go d906a41c2e first commit vor 2 Tagen
pty_netbsd.go d906a41c2e first commit vor 2 Tagen
pty_openbsd.go d906a41c2e first commit vor 2 Tagen
pty_solaris.go d906a41c2e first commit vor 2 Tagen
pty_unsupported.go d906a41c2e first commit vor 2 Tagen
run.go d906a41c2e first commit vor 2 Tagen
start.go d906a41c2e first commit vor 2 Tagen
start_windows.go d906a41c2e first commit vor 2 Tagen
test_crosscompile.sh d906a41c2e first commit vor 2 Tagen
winsize.go d906a41c2e first commit vor 2 Tagen
winsize_unix.go d906a41c2e first commit vor 2 Tagen
winsize_unsupported.go d906a41c2e first commit vor 2 Tagen
ztypes_386.go d906a41c2e first commit vor 2 Tagen
ztypes_amd64.go d906a41c2e first commit vor 2 Tagen
ztypes_arm.go d906a41c2e first commit vor 2 Tagen
ztypes_arm64.go d906a41c2e first commit vor 2 Tagen
ztypes_dragonfly_amd64.go d906a41c2e first commit vor 2 Tagen
ztypes_freebsd_386.go d906a41c2e first commit vor 2 Tagen
ztypes_freebsd_amd64.go d906a41c2e first commit vor 2 Tagen
ztypes_freebsd_arm.go d906a41c2e first commit vor 2 Tagen
ztypes_freebsd_arm64.go d906a41c2e first commit vor 2 Tagen
ztypes_freebsd_ppc64.go d906a41c2e first commit vor 2 Tagen
ztypes_loong64.go d906a41c2e first commit vor 2 Tagen
ztypes_mipsx.go d906a41c2e first commit vor 2 Tagen
ztypes_netbsd_32bit_int.go d906a41c2e first commit vor 2 Tagen
ztypes_openbsd_32bit_int.go d906a41c2e first commit vor 2 Tagen
ztypes_ppc64.go d906a41c2e first commit vor 2 Tagen
ztypes_ppc64le.go d906a41c2e first commit vor 2 Tagen
ztypes_riscvx.go d906a41c2e first commit vor 2 Tagen
ztypes_s390x.go d906a41c2e first commit vor 2 Tagen

README.md

pty

Pty is a Go package for using unix pseudo-terminals.

Install

go get github.com/creack/pty

Examples

Note 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.

Command

package main

import (
	"io"
	"os"
	"os/exec"

	"github.com/creack/pty"
)

func main() {
	c := exec.Command("grep", "--color=auto", "bar")
	f, err := pty.Start(c)
	if err != nil {
		panic(err)
	}

	go func() {
		f.Write([]byte("foo\n"))
		f.Write([]byte("bar\n"))
		f.Write([]byte("baz\n"))
		f.Write([]byte{4}) // EOT
	}()
	io.Copy(os.Stdout, f)
}

Shell

package main

import (
        "io"
        "log"
        "os"
        "os/exec"
        "os/signal"
        "syscall"

        "github.com/creack/pty"
        "golang.org/x/term"
)

func test() error {
        // Create arbitrary command.
        c := exec.Command("bash")

        // Start the command with a pty.
        ptmx, err := pty.Start(c)
        if err != nil {
                return err
        }
        // Make sure to close the pty at the end.
        defer func() { _ = ptmx.Close() }() // Best effort.

        // Handle pty size.
        ch := make(chan os.Signal, 1)
        signal.Notify(ch, syscall.SIGWINCH)
        go func() {
                for range ch {
                        if err := pty.InheritSize(os.Stdin, ptmx); err != nil {
                                log.Printf("error resizing pty: %s", err)
                        }
                }
        }()
        ch <- syscall.SIGWINCH // Initial resize.
        defer func() { signal.Stop(ch); close(ch) }() // Cleanup signals when done.

        // Set stdin in raw mode.
        oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
        if err != nil {
                panic(err)
        }
        defer func() { _ = term.Restore(int(os.Stdin.Fd()), oldState) }() // Best effort.

        // Copy stdin to the pty and the pty to stdout.
        // NOTE: The goroutine will keep reading until the next keystroke before returning.
        go func() { _, _ = io.Copy(ptmx, os.Stdin) }()
        _, _ = io.Copy(os.Stdout, ptmx)

        return nil
}

func main() {
        if err := test(); err != nil {
                log.Fatal(err)
        }
}