Shells

Shells are used to abstract away the inner workings of shtk, and are meant to be the primary interface end users interact with. shtk.Shell instances serve as the standard mechanism for building and running command pipelines.

shtk.Shell

class shtk.Shell(cwd=None, env=None, umask=None, stdin=None, stdout=None, stderr=None, exceptions=True, user=None, group=None)

Bases: object

A shell object tracks pre-requisite information (e.g. cwd and environment variables) necessary to run commands as subprocesses. A shell is also a context manager that exposes environment variables and other info to subshells and subprocesses, while also setting itself as the default shell within managed code.

Parameters
  • cwd (str, pathlib.Path) – Current working directory for subprocesses.

  • env (bool) – If provided Shell will use these key-value pairs as environment variables. Otherwise Shell inherits from the currently active Shell, or _default_shell.

  • umask (int) – Controls the default umask for subprocesses

  • stdin (file-like) – Default stdin stream for subprocesses (defaults to sys.stdin)

  • stdout (file-like) – Default stdout stream for subprocesses (defaults to sys.stdout)

  • stderr (file-like) – Default stderr stream for subprocesses (defaults to sys.stderr)

  • exceptions (bool) – Whether exceptions should be raised when non-zero exit codes are returned by subprocesses.

  • user (None, int, str) – Run subprocesses as the given user. If None, run as same user as this process. If int, run as user with uid=user. If str, run as user with name=user. Requires Python >= 3.9.

  • group (None, int, str) – Run subprocesses as the given group. If None, run as same group as this process. If int, run as group with gid=group. If str, run as group with name=group. Requires Python >= 3.9.

command(name)

Creates a PipelineProcessFactory suitable for executing a command

Parameters

name (str or pathlib.Path) –

Name or path of the command to run. If an absolute or relative path is provided (must contain a ‘/’ character) then the command will be loaded from the specified location. Otherwise the locations specified by the $PATH environment variable will be checked for suitable executable and readable files with the appropriate name.

If name is an str, then the name will be passed through os.path.expanduser prior to lookup.

Returns

A PipelineProcessFactory node representing the command to be executed.

Return type

PipelineProcessFactory

Raises
  • RuntimeError – command cannot be found

  • RuntimeError – command filepath is not readable

  • RuntimeError – command filepath is not executable

cd(path)

Changes the default current working directory for subprocesses built by the Shell

Parameters

path (str or pathlib.Path) – Changes directory to provided path such that managed subprocesses will use this directory as their default current working directory. If ‘-’ is provided, returns to previous working directory.

Raises

RuntimeError – raised if path is not a directory

cd_manager(new_wd)

Contextmanager for Shell.cd() returns to previous dir after exit

Parameters

new_wd (str or pathlib.Path) – directory to change to

Yields

pathlib.Path – The new self.cwd

export(**env)

Sets environment variables passed as keyword arguments

Parameters

**env (dict) – List of key-value pairs that will set as environment variables for the Shell()

getenv(name)

Gets the value of an environment variable within the Shell

Parameters

name (str) – Name of the environment variable to evaluate

Returns

The value of the named environment variable

Return type

str

classmethod get_shell()

Gets the current active shell from the shell stack

Returns

The most recently entered shell context

Return type

Shell

run(*pipeline_factories, exceptions=None, wait=True, close_fds=True)

Executes a series of PipelineNodeFactory nodes as subprocesses

Parameters
  • *pipeline_factories – The PipelineNodeFactory nodes to execute. If multiple arguments are provided, then the commands will run in parallel.

  • exceptions – Whether or not to raise exceptions for non-zero exit codes (Default value = None, meaning inherited)

  • wait – Whether the call should block waiting for the subprocesses to exit (Default value = True)

  • close_fds (bool) – If true, close_fds will be passed to the equivalent of subprocess.Popen() (Default value = True).

Returns

Job instances representing individual pipelines. The length of the list will always be equal to the len(pipeline_factories)

Return type

list of Job

evaluate(pipeline_factory, *, exceptions=None)

Executes a PipelineNodeFactory and returns the stdout text

Parameters
  • pipeline_factory (PipelineNodeFactory) – the pipeline to instantiate and execute

  • exceptions – Whether or not to raise exceptions when subprocesses return non-zero return codes (Default value = None)

Returns

A string generated by the text that the final subprocess writes to stdout

Return type

str or bytes

source(filepath, *, exceptions=None)

Use /bin/sh to source a file, then import the resulting environment as the shtk.Shell’s new environment.

This method uses (approximately) the following kludge:

q = shlex.quote
exec = str(sys.exec or 'python3')
kludge = '''
import json, os, sys;
fout = os.fdopen(int(sys.argv[1]), "w");
json.dump(dict(os.environ), fout);
fout.close();
'''
args = (".", q(path), '&&', q(exec), '-c', q(kludge), str(int(pipe_fd)))
pipeline_factory = shcmd('-c', " ".join(args))
...
Parameters
  • filepath (str or pathlib.Path) – path to file to be sourced. It will be converted to an absolute path before sourcing for compatability with picky shells (e.g. dash).

  • exceptions (bool) – Whether or not to raise exceptions when subprocesses return non-zero return codes (Default value = None)

Returns

A string generated by the text that the final subprocess writes to stdout

Return type

str or bytes