Shells are one of the three parts of a machine: The shell defines the methods
to interact with the machine. For Linux, the shell will usually be
tbot.machine.linux.Bash, a shell implementation for interacting
tbot does not impose any restrictions on how a shell interface is supposed to
look like. It does make sense to keep it close to existing implementations
though, as long as that is feasible. Look at the
LinuxShell class for inspiration.
A lot of shells have an
.interactive() method which allows accessing the
machine’s console directly. This works similar to a terminal-emulator like
picocom or screen. The default testcases
using this mechanism, for example.
- class tbot.machine.shell.Shell¶
- abstract _init_shell() → ContextManager¶
Initialize this shell.
An implementation of this method should return a context manager that, when entered, waits for the shell to appear on the channel and sets up any necessary options. This might include deactivating line-editing, disabling the history, etc.
The most comfortable way to implement this is using
class Shell(tbot.machine.shell.Shell): @contextlib.contextmanager def _init_shell(self): try: # Wait for shell to appear ... # Setup options ... yield None finally: # Optionally destruct shell ...
- abstract exec(*args: Any) → Any¶
Run a command using this shell.
This is the only “common” interface tbot expects shells to implement. The exact semantics of running commands are up to the implementor. This especially includes the return value.
.exec()should take the command as one argument per command-line token. For example:
mach.exec("echo", "Hello", "World")
The return value should in some way be related to the “output” of the command. For
execreturns a tuple of the return code and console output:
- class tbot.machine.shell.RawShell¶
Absolute minimum shell implementation.
RawShellattempts to be a minimal shell implementation. It does not make any assumptions about the other end. It is used, for example, for raw board-console access which allows debugging before U-Boot is fully working.
- exec(*args: str) → None¶
" ".join(args)to the machine’s channel.
exec()implementation has no way of reading back the command output.