interactive

package module
v0.0.0-...-adcf8a8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 11, 2018 License: MIT Imports: 7 Imported by: 2

README

interactive 🐚

Interactive is a package for easily executing and interacting with CLI commands using channels. Uses a PTY and simple channels for inputting lines of strings and reading lines of strings. You can always go direct to the running process and write bytes, though, too. A cool example of this in use is my headlessChrome package which starts headless chrome with --repl (a command line javascript console interface) for very, very realistic website automation.

Automate any command line task with a go program! Special thanks to github.com/kr/pty

Get It

go get -u github.com/integrii/interactive

Read the Godoc

https://godoc.org/github.com/integrii/interactive

Example


func main() {
  // Start the command "bc" (a CLI calculator)
  bc, err := interactive.NewSession("bc", []string{})
  if err != nil {
    panic(err)
  }

  // start a concurrent output reader from the output channel of our command
  go outputPrinter(bc.Output)

  // write 1 + 1 to the bc prompt
  bc.Write(`1 + 1`)

  // wait one second for the output to come and be displayed
  time.Sleep(time.Second)

}

func outputPrinter(c chan string) {
  for s := range c {
    fmt.Println(s)
  }
}

This will print to the console the following:

bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
1 + 1
2

You can run and control nearly anything you could from your console this way.

Documentation

Overview

Package interactive allows you to easily execuate and interact with processes using Go channels.

Index

Examples

Constants

This section is empty.

Variables

View Source
var Debug bool

Debug enables debug output for this package to console

Functions

This section is empty.

Types

type Session

type Session struct {
	StdIn  io.Writer   // input to be written to the console
	StdOut io.Reader   // output coming from the console
	StdErr io.Reader   // error output from the shell
	Input  chan string // incoming lines of input
	Output chan string // outgoing lines of input
	Cmd    *exec.Cmd   // cmd that holds this cmd instance
	// contains filtered or unexported fields
}

Session is an interactive console session for the specified command and arguments.

func NewSession

func NewSession(command string, args []string) (*Session, error)

NewSession starts a new interactive command session

Example

ExampleNewSession shows how to make a new interactive session with a command. Output comes from the string channel bc.Output while iput is passed in with the bc.Write func. Note that we named the interactive session "bc" here because we're running bc.

package main

import (
	"fmt"
	"time"

	"github.com/integrii/interactive"
)

func main() {
	// Start the command "bc" (a CLI calculator)
	bc, err := interactive.NewSession("bc", []string{})
	if err != nil {
		panic(err)
	}

	// start a concurrent output reader from the output channel of our command
	go func(outChan chan string) {
		for s := range outChan {
			fmt.Println(s)
		}
	}(bc.Output)

	// wait a second for the process to init
	time.Sleep(time.Second)

	// write 1 + 1 to the bc prompt
	bc.Write(`1 + 1`)

	// wait one second for the output to come and be displayed
	time.Sleep(time.Second)
}
Output:

func NewSessionWithTimeout

func NewSessionWithTimeout(command string, args []string, timeout time.Duration) (*Session, error)

NewSessionWithTimeout starts a new session but kills it if it runs longer than the specified timeout. Pass 0 for no timeout or use NewSession()

Example

ExampleSessionWithOutput shows how to start a command that only runs for one second before being killed. The 1 + 1 operation never happens becauase the command is killed prior to its running

package main

import (
	"log"
	"time"

	"github.com/integrii/interactive"
)

func main() {

	bc, err := interactive.NewSessionWithTimeout("bc", []string{}, time.Duration(time.Second))
	if err != nil {
		log.Fatal(err)
	}

	time.Sleep(time.Second * 2)
	bc.Write(`1 + 1`) // this will never happen and there will not be any output
}
Output:

func (*Session) Close

func (i *Session) Close() error

Close shuts down the interative session tty cleanly

func (*Session) Exit

func (i *Session) Exit()

Exit exits the running command and closes the input channel

func (*Session) ForceClose

func (i *Session) ForceClose()

ForceClose issues a force kill to the command (SIGKILL)

func (*Session) Init

func (i *Session) Init() error

Init runs things required to initalize a session. No need to call outside of NewInteractiveSession (which does it for you)

func (*Session) Write

func (i *Session) Write(s string)

Write writes an output line into the session

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL