Switch branches/tags
Nothing to show
Latest commit 6f9e61c May 20, 2017 @LLFourn LLFourn Bump v0.0.28

Spook in the Shell Script (Spit-sh) Build Status

Spook in the Shell (Spit or Spit-sh), is Perl-6-like language and compiler for producing modular, dynamic and testable shell scripts. Its purpose is to specify and test configurations for modern UNIX-like systems. It's very new and experimental and doesn't do a lot yet.

Where it fits

Here are a few of the goals of Spit-sh as a configurtion utility:

  • It shouldn't require any software on the target system other than /bin/sh, the POSIX shell utilities and a package manager.
  • It shouldn't try and handle delivery of the scripts to the target system. (Other tools can do this).
  • It should be appropriate for specifying container images.
  • It must be easy to write, document, test and distribute modules.
  • Like Perl 6:
    • It must be test-centric and have a specification test suite written in the language itself.
    • The core classes, symbols and routines should be defined in the language itself.
    • It must be -Ofun 👻🐚💕🦋


To get a picture of where Spit is going take a look at this code:

.install unless Pkg<nc>; # install nc unless it's already there
ok Cmd<nc>,"nc command exists now"; # test the nc command is there

You can compile this for CentOS with:

spit --os=centos eval '.install unless Pkg<nc>; ok Cmd<nc>,"nc command exists now"'

Which ouputs the following shell at the time of writing:

  e(){ printf %s "$1"; }
  exec 4>/dev/null
  installed(){ yum list installed "$1" >&4 2>&4; }
  install(){ yum install -y $1 >&4 2>&4; }
  exists(){ command -v "$1" >&4; }
  exec 3>&1
  say(){ printf '%s\n' "$1" >&3; }
  note(){ printf '%s\n' "$1" >&2; }
  die(){ note "$1" && kill "-TERM" $$ >&4; }
  ok(){ test "$1" && say "✔ - $2" || die "✘ - $2"; }
  if ! installed nc; then
    install nc
  ok "$(exists nc && e 1)" 'nc command exists now'

If you have docker installed you can test this with:

# --in-docker --rm's the container
spit eval '.install unless Pkg<nc>; ok Cmd<nc>,"nc command exists now"' --in-docker=centos
✔ - nc command exists now

Unfortunately on Debian the package is named 'netcat'. Let's deal with that:

# install-nc.spt
constant Pkg $nc = on {
    Debian { 'netcat' }
    Any    { 'nc' } # the default

.install unless $nc;
ok Cmd<nc>,"nc command exists now";

And now it should work on both the RHEL and Debian families of Linux distributions.

spit --in-docker=debian:latest compile install-nc.spt
✔ - nc command exists now


Spit is written in Perl 6 and requires rakudo and something to install Perl 6 ecosystem modules with like zef.

zef install Spit

and run

spit eval 'say "hello world"'

To check it's working.

note rakudo star is too far behind at the moment. You need to build from rakudo/nom because Spit uses some features recently added to rakudo. Hopefully it will keep compatibility with rakudo star in the future.


Documentation is very much a work in progress but what exists is under: doc/.

Project Layout

  • The Perl 6 Spit compiler module is in lib
  • The actual Spit source code is under resources/src
  • The core spit modules are under resouces/core-lib (right now just Test.spt)
  • The spec tests are in spec.


There's a lot to do before Spit becomes a genuinely useful tool.

  • If you like grammars and abstract syntax trees you can help develop the compiler
  • You can add support for an operating system/userland by writing Spit code that passes the spec tests
  • Try it out, provide bug reports, useful criticism and feature ideas under the issues github tab
  • Figure out how it works and write documentation