packages feed

shebanger-1.0.0.0: README.md

# shebanger

`shebanger` is a small CLI tool to transform a _boring_ shell script into an
**exciting** series of shebang lines!

`shebanger` takes a shell script as input, and outputs a series of shell
scripts. Each of the output shell scripts only consists of a shebang line, they
don't have any code in their body.  Executing the first output shell script will
run your original input shell program.

## Installation

This section lists installation instructions for various Linux distros.

### Generic Linux

There is a statically-linked x86\_64 Linux ELF binary for `shebanger` available on each of
the [GitHub Releases](https://github.com/cdepillabout/shebanger/releases).

### Nix / NixOS

Cloudy can be built with Nix by using the `.nix` files in this repo:

```console
$ nix-build
```

You can find the `shebanger` binary in `./result/bin/shebanger`.

You can also install `shebanger` from Nixpkgs by using the `haskellPackages.shebanger`
derivation:

```console
$ nix-build '<nixpkgs>' -A haskellPackages.shebanger
```

### Other Distros

PRs are welcome adding instructions for installing Cloudy on other Linux
distributions!

## Usage

`shebanger` assumes it will be available on your `PATH`.  You might see errors
with the following commands if `shebanger` can't be found on your `PATH`.

There is an example shell script to use with `shebanger` in this repo called
[`test.sh`](./test.sh):

```console
$ cat test.sh
#!/usr/bin/env bash

echo "arguments to this script: $@"
...
```

First, run `shebanger` on this script:

```console
$ shebanger ./test.sh
```

This outputs a bunch of scripts named like the following:

```console
$ ls test.sh.shebanged*
test.sh.shebanged
test.sh.shebanged.1
test.sh.shebanged.2
test.sh.shebanged.3
test.sh.shebanged.4
test.sh.shebanged.5
...
```

Each of these scripts is just a single line, and they look like the following:

```console
$ cat ./test.sh.shebanged
#!/usr/bin/env -S shebanger exec IyEvdXNyL2Jpbi9lbnYgYmFzaAoKZWNobyAiYXJndW1lbnRzIHRvIHRoaXMgc2NyaXA=
```

You can see that this is a script that only consists of a shebang line.  The
contents of the original script are split into 50-byte chunks, base-64 encoded,
passed within the shebang lines of the output scripts.

If you run `./test.sh.shebanged`, the original `test.sh` will be reconstructed
and executed:

```console
$ ./test.sh.shebanged hello this is an argument
arguments to this script: hello this is an argument
...
```

## How Does `shebanger` Work?

`shebanger` works by base-64-encoding the original input script, and splitting
it up into the shebang lines of a series of output scripts.  Each of these
output scripts consist of only a shebang line.

When running the output script, by executing each output script one-by-one in
turn, `shebanger` collects the contents of the original script, reconstructs
it, and executes it.

`shebanger` actually doesn't require the input to be a script, it works on any
executable.  However, see the following sections on limitations of this.

## Limitations

Currently `shebanger` collects the contents of the original scripts into an
environment variable, and passes that along when `exec`'ing the next script.

This means that `shebanger` is not able to execute scripts longer than a few
hundred kilobytes, since they tend to overflow the max size of all environment
variables.

## Inspiration

`shebanger` is inspired by [bangscript](https://github.com/viperML/bangscript)
by [@viperML](https://github.com/viperML).  The `About` explanation of `bangscript` is:

> Embed scripts in a shebang

When I read this, I immediately thought it would be what `shebanger` currently
is.  Since `bangscript` is instead something actually useful, I knew I needed to write
`shebanger`.

## FAQs

1.  **Q: Why would someone ever actually use `shebanger`?**

    A: ...