This program allows you to send commands to a shell process as if they were typed by a human. runner
takes simple configuration files as an input and uses Pexpect to allow for interaction with pretty much every tool that has a command-line interface.
This program will be installed as an executable called runner
by default. runner
takes a .yaml
file as an input and runs commands according to the instructions in the YAML file. For more information on how to write config files, see Writing a configuration file or an example.
runner [PATH/TO/CONFIG]
To try it out, you can run
runner tests/examples/test_conf.yaml
from the root of this repo.
If you installed this program with Docker, you will need to pass your script to
the container. To do so, you can use the --volume
flag to bind mount your
current directory to a location inside the container.
First, navigate to a directory that has your script in one of it's child directories. Then, run
docker run --volume $PWD:/data [image-name] [path/to/script]
where:
-
[image-name]
needs to be replaced by the name of your docker image. -
[path/to/script]
is the path towards your script from your current working directory.
runner
can be installed using pip
. This means that you need a working installation of Python and Pip. See: https://pip.pypa.io/en/stable/installing/.
Since this program is not distributed on pypi, you will need to download a copy of this repo first. This can be done by downloading the .zip
archive or by cloning this repo.
If you already have Docker installed on your system, you can simply pull the image to get started.
docker pull trickytroll/good-bot-runner:latest
You should download the latest release on the release page. From the releases page:
- Click
Source code
. - Unzip the downloaded archive.
- From a terminal, navigate to the unzipped directory.
Once you are at the root of the downloaded folder, run
pip install -U .
This will install a program called runner
for you (the user running the command).
To get the latest unreleased copy of this program, you should clone the repository instead of downloading a release. The main
branch is updated less frequently than the latest
one, but the code on main
is tested more thoroughly.
Note: There is no guarantee that code outside of the
main
branch is frequently tested.
From your terminal:
git clone https://github.com/TrickyTroll/good-bot-runner.git
Then, go to the root of the cloned repo and run:
pip install -U .
This will install a program called runner
for you (the user running the command).
On the repos main page:
- Click on
Code
. - Then on
Download ZIP
.
Once the archive is extracted, run
pip install -U .
from a terminal at the root of the folder you just downloaded. This will install a program called runner
for you (the user running the command).
This project is not tested regularly on Windows. For a smoother experience, I recommend using this app in a containerized Linux environment. ~~~~
After it is done parsing the configuration, runner
spawns a shell process and sends the first command. That is, the first element in the list associated with the key commands
. It then waits until the shell responds to something that matches the first element in the list associated to the expect
key.
After this first interaction with the shell process, runner
will keep sending succeeding commands and expect something to be returned by the shell. If the expected value is not showing up, the default timeout
is set at 30 seconds. After that, the object Python uses to represent the process will raise an error.
Once every command has been sent and the last expectation has been met, the program will close the shell process.
Python should interpret the YAML file as a dictionary that maps commands and expectations. One configuration file should correspond to one sequence of interactions. This means that the dictionary representation of the setup should only contain two keys.
One of the two keys is commands
. In YAML, you should write an unindented commands:
. Python will interpret this as the key to the following value or values.
Since you could run more than one command and you probably want those commands to be ordered, the value associated with commands
is a list. In the configuration file, a list is represented by items with a -
at the beginning of the line. Each item has its own line. Since this list is associated with commands
, it can be indented to make it easier to understand.
commands:
- echo 'hello world'
- ls
Note: Even if you only want to run one command, you must write it as a list. This is due to the fact that
runner
will iterate over the items associated withcommands
, assuming that it is a list. A string is also iterable, but the result of each iteration won’t be a functional shell command (probably).
runner
also supports the use of secrets and passwords. Passwords are necessary when recording
commands that must be run as root, for example. They can also be used to connect to a remote
machine thanks to ssh
with a password.
Passwords are sent to the program with the help of environment variables. If you are running runner
directly on your machine, you can set those variables using the export
command. This example
binds a password to the SOME_PASSWORD
variable. This variable can then be used in
your script to respond to a password prompt.
export SOME_PASSWORD=popcorn-TUB-pigskin-randy
Please note that this only works on UNIX-like systems. If you are using Windows, you will get a much smoother experience with the Docker image.
If you are using the Docker image, you can write a text file that contains all of your variables on different lines.
SOME_PASSWORD=popcorn-TUB-pigskin-randy
ANOTHER_PASSWORD=odious-cloy-SQUIRE-register
Then, when using the docker run
command, add the --env-file
flag to your command with
the path towards your text file as an argument.
When writing the .yaml
configuration file, you can tell runner
which environment
variable to look for with the password
keyword.
commands:
- ssh some-user@dev-machine
- password: SOME_PASSWORD
expect:
- assword
- prompt
This last example will use the previously set SOME_PASSWORD
variable to answer to the
ssh command's password prompt.
You can set as many variables as you want, but your passwords should be replaced after being used with this program.
⚠️ Warning: While version controlling your documentation scrips can be a good idea, always be careful not to add your.env
files to your version control history. It is also a strongly recommended that the passwords used withrunner
are removed from your systems and applications afterwards.
The only other key that you should put in your configuration file is expect
. As with the commands
key, expect should not be indented and written like so:
expect:
This time, the list will contain things to expect before sending the next command to the shell process. Items in this list can be regular expressions.
Note: This is useful if you are recording a demo where you need to login somewhere. You could expect something like
assword:
before sending your credentials.
Theprompt
keyword can also be used to expect the next time the prompt will show up. For now, this only matches the#
character. This is usually the root prompt.
expect:
- prompt
- prompt