Usage Examples

A simple multi-file application

This example demonstrates an application that runs with multiple script files that are called with the include() function.

Imagine we have the following files:

start.sh

This is an optional starter script. Placing the startup methods here is just for convenience and can be placed in the main script instead. It is mostly useful if you intend to compile the scripts to form a single script, since when you do so, you would only have to target the main file, and exclude the starter file.

#!/bin/sh

# load loader.sh
. ./loader.sh

# Add directories to search path.
loader_addpath source

# Load main script.
load main.sh

source/main.sh

include a.sh
include b.sh

echo '---- main.sh ----'

# Remove loader from shellspace since we no longer need it.
loader_finish

# Main procedures go from here.

# ...

source/a.sh

include main.sh
include a.sh
include b.sh

echo '---- a.sh ----'

source/b.sh

include main.sh
include a.sh
include b.sh

echo '---- b.sh ----'

Output

The final file structure should be like this:

loader.sh
start.sh
source/a.sh
source/b.sh
source/main.sh

Now if we run start.sh, this is what we would get:

$ sh start.sh
---- b.sh ----
---- a.sh ----
---- main.sh ----

You can download the demo files here.

Compiling

If we want to compile the code, we could do it with a command like this. See next page for more information about compilers.

$ gawk -f compiler.gawk -- -a source -O -s '/bin/sh' -o compiled.sh source/main.sh
compiler: truncate: compiled.sh
compiler: truncate: compiler.main.obj
compiler: truncate: compiler.calls.obj
compiler: truncate: compiler.comp.obj
compiler: walk: /home/base/t/source/main.sh
compiler: walk: /home/base/t/source/a.sh
compiler: walk: /home/base/t/source/b.sh
compiler: dump: compiler.calls.obj >> compiler.comp.obj
compiler: remove file: compiler.calls.obj
compiler: dump: compiler.main.obj >> compiler.comp.obj
compiler: remove file: compiler.main.obj
compiler: strip: compiler.comp.obj
compiler: add #! header: "#!/bin/sh" > compiled.sh
compiler: dump: compiler.comp.obj >> compiled.sh
compiler: remove file: compiler.comp.obj

Notice that we didn’t use start.sh as a target, but source/main.sh instead.

After running the command, we get compiled.sh as the output file. This is what it would contain:

#!/bin/sh

echo '---- b.sh ----'

echo '---- a.sh ----'

echo '---- main.sh ----'

(EOF)

Running it would give the same output as above:

$ sh compiled.sh
---- b.sh ----
---- a.sh ----
---- main.sh ----

For more information on how to use the compiler, run it with the --help option.

Extended Version Examples

Here are some ways to use extended functions:

# Same as 'load plain.sh'
loadx plain.sh

# Loads all files ending with .sh
loadx '*.sh'

# Includes all files in source/ that ends in .bash
includex 'source/*.bash'

# Includes all files in /usr/share/scripts/bash/ that ends in .bash
includex '/usr/share/scripts/bash/*.bash'

# Calls all scripts in objects that ends in .sh (not case sensitive) in
# a subshell
callx -iname 'objects/*.sh'

# Calls all scripts in modules that end in .sh
callx -regex 'modules/.*\.sh$'

Next Page: Compilers