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

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)
        }
}