Package term

import "gitlab.com/zoralab/cerigo/os/term"

Package term is a control unit to interface with command line interface.

It uses multiple standard library packages like os, os/exec, and etc. to build itself and extend the original os/exec terminal.

Differences between os/exec

Here are some of the differences between Cerigo os/term package with the the standard package os/exec:

  1. Unified command line into single line rather than split arguments.

  2. Formulate Terminal object in Go codes, allowing addition of individual Commands.

  3. Independent command management.

  4. Extend os/exec asynchonous implementation.

  5. Do not support Stdin. Use properly formatted command as a replacement before feeding it into the terminal or start the execution. Example: $ echo y | sudo apt-get install gimp

Example

var t *Terminal
var c *Command
var err error
var stdout, stderr []byte

t = NewTerminal(BASHTerminal)

if t.IsRoot() {
fmt.Printf("I have root permission")
}

stdout, stderr, err = t.Execute("ls /", 5*1000*1000)
if err != nil {
fmt.Printf("handle error: %v\n", err)
}

fmt.Printf("stdout: %v\nstderr: %v\n", stdout, stderr)

err = t.Add("myCommandLabel", "ls /", 5*1000*1000)
if err != nil {
fmt.Printf("handle error: %v\n", err)
}

c, err = t.Run("myCommandLabel", true)
if err != nil {
fmt.Printf("handle error: %v\n", err)
}

stdout, stderr = c.ReadOutput()

fmt.Printf("stdout: %v\nstderr: %v\n", stdout, stderr)

c, err = t.Run("myCommandLabel", false)
if err != nil {
fmt.Printf("handle error: %v\n", err)
}

c.Wait()

Constants

const (
	// NoTerminal is the terminalType for No terminal
	// interpreter
	NoTerminal = uint(0)

	// BASHTerminal is the terminalType for BASH terminal
	// interpreter
	BASHTerminal = uint(1)

	// SHTerminal is the terminalType for SHELL terminal
	// interpreter
	SHTerminal = uint(2)

	// DOSTerminal is the terminalType for MSDOS terminal
	// interpreter
	DOSTerminal = uint(3)
)

statusID for all PrintStatus status value.

const (
	// NoTagStatus is the statusID for PrintStatus not to append
	// any tag This is the Default.
	NoTagStatus = uint(0)

	// InfoStatus is the statusID for PrintStatus to append tag
	// [ INFO ]
	InfoStatus = uint(1)

	// ErrorStatus is the statusID for PrintStatus to append tag
	// [ ERROR ]
	ErrorStatus = uint(2)

	// WarningStatus is the statusID for PrintStatus to append
	// tag [ WARNING ]
	WarningStatus = uint(3)

	// DebugStatus is the statusID for PrintStatus to append tag
	// [ DEBUG ]
	DebugStatus = uint(4)
)

Command

type Command struct {
	Timeout uint64
	// contains filtered or unexported fields
}

Command structure is an object that holds a single os.exec command operation.

It has a Timeout for setting up a bail-out sequences in case of a given dud command. The Timeout is strictly nanoseconds. If 0 is provided, it carries out the default timeout which is 60 seconds.

You cannot alter the command directly in this structure. For that, you should use the Terminal.Update(...) function.

Func (c *Command) ReadError() (err error)

ReadError returns the error value found from the command execution.

This function relies on its mutex synchonization to avoid data races.

Func (c *Command) ReadOutput() (stdout []byte, stderr []byte)

ReadOutput returns STDOUT and STDERR outputs returned from the execution.

This function relies on its mutex synchonization to avoid data races.

Func (c *Command) Run()

Run executes the command synchonously.

Under the hood, Run() runs Start() and Wait() in sequence.

Func (c *Command) Start()

Start executes the command asynchonously.

Func (c *Command) Wait()

Wait runs the waiting and post data process after Start().

Terminal

type Terminal struct {
	// contains filtered or unexported fields
}

Terminal is the Cerigo’s Go terminal that holds various user’s custom commands.

There are private variables in the structure so use the NewTerminal(...) function to create your terminal object.

Func NewTerminal(terminalPrefix uint) *Terminal

NewTerminal creates the terminal object. It accepts terminalPrefix parameter.

The terminalPrefix is to facilitate terminal interpretations. This setting is persisted inside the Terminal settings.

The default is NoTerminal.

Func (t *Terminal) Add(label string, command string, timeout uint64) error

Add is to create the given command string into the terminal with its timeout.

If the timeout is 0, the generated Command object falls back to default timeout which is 60 seconds. This is for handling dud commands that holds the control forever.

If the given label is found to be associated with an existing Command, Add(...) will return an error.

Func (t *Terminal) Delete(label string)

Delete removes an existing command in the terminal regardlessly.

Func (t *Terminal) Execute(command string, timeout uint64) (stdout []byte, stderr []byte, err error)

Execute is to execute a given command string synchonously and without persisting inside the terminal object.

This is for quick execution without needing to build up your own terminal.

It takes inputs of:

  1. command - which is your command line.
  2. timeout - timeout to kill the command. Set to 0 for default 2 minutes. the unit is nanoseconds.

It returns:

  1. stdout, stderr, nil - successfully ran command with no error.
  2. stdout, stderr, err - successfully ran command but with error.

Func (t *Terminal) Get(label string) *Command

Get seeks the registered command from the terminal and returns it to you.

If the command is not found, it will return nil.

Func (t *Terminal) IsRoot() bool

IsRoot is to check whether the terminal has root access.

Func (t *Terminal) PrintStatus(statusID uint, format string, a ...interface{})

PrintStatus is to output a given input string to the STDERR output channel.

It uses fmt.Printf(...) as its primary printout with suppressed error. Hence, to use PrintStatus(...), you just need to state the statusID first and use then use it like fmt.Printf(...).

PrintStatus accepts statusID based on the constant values in this package. By default, the status is NoTagStatus.

Func (t *Terminal) Printf(format string, a ...interface{})

Printf is to output the given input formatting string to the STDOUT channel.

It uses fmt.Printf(…) as its primary printout with suppressed error. Hence, you must ensure your values are correct before passing into Printf.

Func (t *Terminal) Run(label string, mustWait bool) (c *Command, err error)

Run is to execute a registered command both asynchonously and synchonously.

To different them, state the mustWait intention. If Run(...) is set to mustWait, the execution becomes synchonous and will wait for completions before proceeding to next line of Go code.

It returns:

  1. *Command, nil - Command object after successful run.
  2. *Command, err - error encountered.

Func (t *Terminal) Size() (row uint, column uint)

Size is to get a terminal row (height) and column (width) sizes at a given instance. If there is an error occurs, both row and column becomes 0.

Func (t *Terminal) Update(label string, command string, timeout uint64) error

Update is to update the existing Command object with new Command and its timeout.

If the Command object is missing (e.g. bad label), Update(...) returns an error instead.