Documentation
¶
Overview ¶
Package script provides helper functions to write scripts.
Inspired by https://github.com/bitfield/script, with some improvements:
* Output between streamed commands is a stream and not loaded to memory.
* Better representation and handling of errors.
* Proper incocation, usage and handling of stderr of custom commands.
The script chain is represented by a (`Stream`) https://godoc.org/github.com/posener/script#Stream object. While each command in the stream is abstracted by the (`Command`) https://godoc.org/github.com/posener/script#Command struct. This library provides basic functionality, but can be extended freely.
Example (HelloWorld) ¶
A simple "hello world" example that creats a stream and pipe it to the stdout.
// Create an "hello world" stream and use the ToStdout method to write it to stdout. Echo("hello world").ToStdout()
Output: hello world
Example (Iterate) ¶
An example that shows how to iterate scanned lines.
// Stream can be any stream, in this case we have echoed 3 lines. stream := Echo("first\nsecond\nthird") // To iterate over the stream lines, it is better not to read it into memory and split over the // lines, but use the `bufio.Scanner`: defer stream.Close() scanner := bufio.NewScanner(stream) for scanner.Scan() { fmt.Println(scanner.Text()) }
Output: first second third
Example (Through) ¶
An example that shows how to create custom commands using the `Through` method with a `PipeFn` function.
Echo("1\n2\n3").Through(PipeFn(func(r io.Reader) (io.Reader, error) { // Create a command that sums up all numbers in input. // // In this example we create a reader function such that the whole code will fit into the // example function body. A more proper and readable way to do it was to create a new // type with a state that implements the `io.Reader` interface. // Use buffered reader to read lines from input. buf := bufio.NewReader(r) // Store the sum of all numbers. sum := 0 // Read function reads the next line and adds it to the sum. If it gets and EOF error, it // writes the sum to the output and returns an EOF. read := func(b []byte) (int, error) { // Read next line from input. line, _, err := buf.ReadLine() // if EOF write sum to output. if err == io.EOF { return copy(b, append([]byte(strconv.Itoa(sum)), '\n')), io.EOF } if err != nil { return 0, err } // Convert the line to a number and add it to the sum. if i, err := strconv.Atoi(string(line)); err == nil { sum += i } // We don't write anything to output, so we return 0 bytes with no error. return 0, nil } return readerFn(read), nil })).ToStdout()
Output: 6
Index ¶
- func AppendFile(path string) (io.WriteCloser, error)
- func File(path string) (io.WriteCloser, error)
- type Count
- type Cut
- type FileInfo
- type Files
- type Grep
- type Modifier
- type ModifyFn
- type Pipe
- type PipeFn
- type Stream
- func Cat(paths ...string) Stream
- func Echo(s string) Stream
- func Exec(cmd string, args ...string) Stream
- func ExecHandleStderr(stderr io.Writer, cmd string, args ...string) Stream
- func From(name string, r io.Reader) Stream
- func Stdin() Stream
- func Writer(name string, writer func(io.Writer) error) Stream
- func (s Stream) AppendFile(path string) error
- func (s Stream) Close() error
- func (s Stream) Cut(fields ...int) Stream
- func (s Stream) Discard() error
- func (s Stream) Exec(cmd string, args ...string) Stream
- func (s Stream) ExecHandleStderr(stderr io.Writer, cmd string, args ...string) Stream
- func (s Stream) Grep(re *regexp.Regexp) Stream
- func (s Stream) Head(n int) Stream
- func (s Stream) Modify(modifier Modifier) Stream
- func (s Stream) Read(b []byte) (int, error)
- func (s Stream) Sort(reverse bool) Stream
- func (s Stream) Tail(n int) Stream
- func (s Stream) Through(pipe Pipe) Stream
- func (s Stream) To(w io.Writer) error
- func (s Stream) ToFile(path string) error
- func (s Stream) ToStdout() error
- func (s Stream) ToString() (string, error)
- func (s Stream) ToTempFile() (path string, err error)
- func (s Stream) Uniq() Stream
- func (s Stream) Wc() Count
- type Uniq
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AppendFile ¶ added in v1.0.3
func AppendFile(path string) (io.WriteCloser, error)
Types ¶
type Count ¶
type Count struct { // Stream can be used to pipe the output of wc. Stream // Count the number of lines, words and chars in the input. Lines, Words, Chars int }
Count represents the output of `wc` shell command.
type Cut ¶
type Cut struct { // Fields defines which fields will be collected to the output of the command. The fields are 1 // based (first field is 1). Fields []int // Delim is the delimited by which the fields of each line are sparated. Delim []byte }
Cut is a `Modifier` that takes selected fields from each line according to a given delimiter. The default delimiter is tab.
Shell command: `cut -d<Delim> -f<Fields>`.
type FileInfo ¶ added in v1.0.3
type FileInfo struct { // FileInfo contains information about the file. os.FileInfo // Path is the path of the file. It may be relative or absolute, depending on how the `Ls` // command was invoked. Path string }
File contains information about a file.
type Files ¶
Files is a stream of a list of files. A user can either use the file list directly or the the created stream. In the stream, each line contains a path to a file.
func Ls ¶
Ls returns a stream of a list files. In the returned stream, each line will contain a path to a single file.
If the provided paths list is empty, the local directory will be listed.
The provided paths may be relative to the local directory or absolute - this will influence the format of the returned paths in the output.
If some provided paths correlate to the arguments correlate to the same file, it will also appear multiple times in the output.
If any of the paths fails to be listed, it will result in an error in the output, but the stream will still conain all paths that were successfully listed.
Shell command: `ls`.
type Grep ¶
Grep is a modifier that filters only line that match `Re`. If Invert was set only line that did not match the regex will be returned.
Usage:
(<Stream object>).Modify(script.Grep{Re: <re>})
Shell command: `grep [-v <Invert>] <Re>`.
type Modifier ¶ added in v1.0.3
type Modifier interface { // Modify a line. The input of this function will always be a single line from the input of the // stream, without the trailing '\n'. It should return the output of the stream and should // append a trailing '\n' if it want it to be a line in the output. // // When EOF of input stream is met, the function will be called once more with a nil line value // to enable output any buffered data. // // When the return modified value is nil, the line will be discarded. // // When the returned eof value is true, the Read will return that error. Modify(line []byte) (modifed []byte, err error) // Name returns the name of the command that will represent this modifier. Name() string }
Modifier modifies input lines to output. On each line of the input the Modify method is called, and the modifier can change it, omit it, or break the iteration.
type ModifyFn ¶ added in v1.0.3
ModifyFn is a function for modifying input lines.
type Pipe ¶ added in v1.0.3
type Pipe interface { // Pipe gets a reader and returns another reader. A pipe may return an error and a reader // together. Pipe(stdin io.Reader) (io.Reader, error) // Name of pipe. Name() string }
Pipe reads from a reader and returns another reader.
type Stream ¶
type Stream struct {
// contains filtered or unexported fields
}
Stream is a chain of operations on a stream of bytes. The stdout of each operation in the stream feeds the following operation stdin. The stream object have different methods that allow manipulating it, most of them resemble well known linux commands.
A custom modifier can be used with the `Through` or with the `Modify` functions.
The stream object is created by some in this library or from any `io.Reader` using the `From` function. It can be dumped using some functions in this library, to a custom reader using the `To` method.
func ExecHandleStderr ¶
ExecHandleStderr executes a command, returns a stream of the stdout of the command and enable collecting the stderr of the command.
If the stderr is nil, it will be ignored.
For example, collecting the stderr to memory can be done by providing a `&bytes.Buffer` as `stderr`. Writing it to stderr can be done by providing `os.Stderr` as `stderr`. Logging it to a file can be done by providing an `os.File` as the `stderr`.
func (Stream) AppendFile ¶ added in v1.0.1
AppendFile appends the output of the stream to a file.
func (Stream) Close ¶
Close closes all the stages in the stream and return the errors that occurred in all of the stages.
func (Stream) Cut ¶
Cut takes selected fields from each line. The fields are 1 based (first field is 1).
Shell command: `cut -f<Fields>`.
func (Stream) ExecHandleStderr ¶
ExecHandleStderr executes a command, returns a stream of the stdout of the command and enable collecting the stderr of the command.
If the stderr is nil, it will be ignored.
func (Stream) Grep ¶
Grep filters only line that match the given regexp.
Shell command: `grep <re>`.
func (Stream) Head ¶
Head reads only the n first lines of the given reader. If n is a negative number, all lines besides last n lines will be read.
Shell command: `head -n <n>`
func (Stream) Tail ¶ added in v1.0.3
Tail reads only the n last lines of the given reader. If n is a negative number, all lines besides the first n lines will be read.
Shell command: `tail -n <n>`
func (Stream) Through ¶ added in v1.0.3
Through passes the current stream through a pipe. This function can be used to add custom commands that are not available in this library.
func (Stream) To ¶ added in v1.0.3
To writes the output of the stream to an io.Writer and closes it.
func (Stream) ToTempFile ¶ added in v1.0.1
ToTempFile dumps the output of the stream to a temporary file and returns the temporary files' path.