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: ...