Docs

0%

Loading...

Static preview:

Shell

In general, the Goal shell mode behavior mimics that of bash.

The following documentation describes specific use-cases.

Environment variables

  • set (space delimited as in all shell mode, no equals)

Output redirction

  • • Standard output redirect: > and >& (and |, |& if needed)

Control flow

  • • Any error stops the script execution, except for statements wrapped in [ ], indicating an “optional” statement, e.g.:

    & at the end of a statement runs in the background (as in bash) – otherwise it waits until it completes before it continues.

    jobs, fg, bg, and kill builtin commands function as in usual bash.

Shell functions (aliases)

Use the command keyword to define new functions for Shell mode execution, which can then be used like any other command, for example:

The command is transpiled into a Go function that takes args ...string arguments. In the command function body, you can use the args... expression to pass all of the args, or args[1] etc to refer to specific positional indexes, as usual.

The command function name is registered so that the standard shell execution code can run the function, passing the args. You can also call it directly from Go code using the standard parentheses expression.

Script Files and Makefile-like functionality

As with most scripting languages, a file of goal code can be made directly executable by appending a “shebang” expression at the start of the file:

When executed this way, any additional args passed on the command line invocation are available via the goalrun.Args() function, which can be passed to a command as follows:

or by referring to specific arg indexes etc, as in goalrun.Args()[0]. Note that these are not the same as the implicit args for command aliases, which are local function args in effect.

To make a script behave like a standard Makefile, you can define different commands for each of the make commands, and then add the following at the end of the file to use the args to run commands:

See make for an example, in cmd/goal/testdata/make, which can be run for example using:

Note that there is nothing special about the name make here, so this can be done with any file.

The make package defines a number of useful utility functions that accomplish the standard dependency and file timestamp checking functionality from the standard make command, as in the magefile system. Note that the goal direct shell command syntax makes the resulting make files much closer to a standard bash-like Makefile, while still having all the benefits of Go control and expressions, compared to magefile.

TODO: implement and document above.

SSH connections to remote hosts

Any number of active SSH connections can be maintained and used dynamically within a script, including simple ways of copying data among the different hosts (including the local host). The Go mode execution is always on the local host in one running process, and only the shell commands are executed remotely, enabling a unique ability to easily coordinate and distribute processing and data across various hosts.

Each host maintains its own working directory and environment variables, which can be configured and re-used by default whenever using a given host.

    gossh hostname.org [name] establishes a connection, using given optional name to refer to this connection. If the name is not provided, a sequential number will be used, starting with 1, with 0 referring always to the local host.

    @name then refers to the given host in all subsequent commands, with @0 referring to the local host where the goal script is running.

    • You can use a variable name for the server, like this (the explicit $ $ shell mode is required because a line starting with { is not recognized as shell code):

Explicit per-command specification of host

Default host

uses the given host for all subsequent commands (unless explicitly specified), until the default is changed. Use gossh @0 to return to localhost.

Redirect input / output among hosts

The output of a remote host command can be sent to a file on the local host:

Note the use of the : colon delimiter after the host name here. TODO: You cannot send output to a remote host file (e.g., > @host:remotefile.tsv) – maybe with sftp?

The output of any command can also be piped to a remote host as its standard input:

scp to copy files easily

The builtin scp function allows easy copying of files across hosts, using the persistent connections established with gossh instead of creating new connections as in the standard scp command.

scp is always run from the local host, with the remote host filename specified as @name:remotefile

Importantly, file wildcard globbing works as expected:

and entire directories can be copied, as in cp -a or cp -r (this behavior is automatic and does not require a flag).

Close connections

Will close all active connections and return the default host to @0. All active connections are also automatically closed when the shell terminates.

Other Utilties

** TODO: need a replacement for findnm – very powerful but garbage..

Rules for Go vs. Shell determination

These are the rules used to determine whether a line is Go vs. Shell (word = IDENT token):

  • $ at the start: Shell.
  • • Within Shell, {}: Go
  • • Within Go, $ $: Shell
  • • Line starts with go keyword: if no ( ) then Shell, else Go
  • • Line is one word: Shell
  • • Line starts with path expression (e.g., ./myexec) : Shell
  • • Line starts with "string": Shell
  • • Line starts with word word: Shell
  • • Line starts with word {: Shell
  • • Otherwise: Go

TODO: update above

Multiple statements per line

  • • Multiple statements can be combined on one line, separated by ; as in regular Go and shell languages. Critically, the language determination for the first statement determines the language for the remaining statements; you cannot intermix the two on one line, when using ;