mkshz
self extracting shell gzip tarball packager.
- Simple shell script to generate self extracting shell script with embedded gzipped tarball.
- Minimalist universal packager with pre / post install command without any complex package factory to setup.
- Simple deployment of application using unique shell script package.
- Alternative to rpm/deb/… factory for simple projects
prerequisites
- bash
- sed (gnu/bsd)
- tar / gzip
you can use mkshz.compat if using old OS distribution (tar/sed missing features)
usage
usage: mkshz <file.shz> <dir> [<command> [--tmp-exec] [--pre-extract <command>] <tar options>]
Creates a shell script <file.shz>
with embedded tgz archive created from <dir>
content.
- The script will extract the archive to the current directory on execution.
- A
<command>
in<dir>
can be specified to run after extraction with arguments passed to<file.shz>
. - A pre-extract
<command>
in<dir>
can be specified to be extracted and run before the whole archive is extracted. - if
--tmp-exec
flag is set the resulting script will extract to /tmp/shz.XXXX executes the commands and clean the /tmp/shz.XXXXX - shz_version environment variable can be set to get the version of the archive using
v-shz
parameter.
Example usage:
$ shz_version=v1.2 mkshz install.shz app/ bin/config.sh --pre-extract bin/pre-stop.bash --exclude=.git --exclude=*.o
Notes:
- The
<command>
arguments are relative to<dir>
. - The script generated will be created with a shebang line for bash.
- The pre-extract
<command>
will be extracted and executed before extracting whole archive - The pre-extract
<command>
does not receive any arguments. - If the pre-extract
<command>
exit code is not zero, the script will abort whole extraction.
Example
$ shz_version=v1.2 mkshz installapp.shz app bin/setup.sh --pre-extract bin/stopapp.sh --exclude=.git
- Generated script
installapp.shz
:
#!/bin/bash
# Script created with mkshz
# This script extracts embedded tgz archive
# extract archive directory: 'app'
# pre-extract command: 'app/bin/stopapp.sh'
# post-extract command: 'app/bin/config.sh'
# to extract the archive without command execution, use:
# ./installapp.shz x-shz
# shz_verbose=1 env variable can be set to enable tar output
# shz_target_dir can be set to specify the target directory for extraction
#
version="v1.2"
dir="app"
pre="app/bin/stopapp.sh"
cmd="app/bin/config.sh"
tmpexec="1"
shz="${0##*/}"
[ "$shz_verbose" ] && v=v || v=""
[ "$1" = "v-shz" ] && echo "$version" && exit 0
[ "$1" = "x-shz" ] && cmd="" pre=""
[ ! "$shz_target_dir" ] && [ "$tmpexec" ] && {
shz_target_dir=$(mktemp -d /tmp/shz.XXXXXX) || exit 1
[ "$cmd" ] && trap 'rm -rf "$shz_target_dir"' EXIT
}
: ${shz_target_dir:=$PWD}
extract() {
sed '1,/^__tgz__/d' "$0"| (cd "$shz_target_dir" && tar xz${v}f - "$@" >&2) || exit 1
}
# Pre-extract script:
[ "$pre" ] && {
echo "$shz: Extracting/Executing pre-extract script: $pre" >&2
extract "$pre"
"$shz_target_dir/$pre" || { echo "$shz: Error: Failed to execute pre-extract script ($pre)" >&2; exit 1; }
}
echo "$shz: Extracting archive directory '$dir' in '$shz_target_dir'" >&2
extract
[ "$cmd" ] || exit 0
cmd="$shz_target_dir/$cmd"
echo "$shz: Executing command: $cmd $*" >&2
[ ! -x "$cmd" ] && echo "$shz: Error: Command $cmd not found or not executable." >&2 && exit 1
"$cmd" "$@"
exit $?
__tgz__ ====== binary data starts here ==========================================
- script execution
user@host:/myapp/distrib $ ./installapp.shz --register myhost
installapp.shz: Extracting/Executing pre-extract script: app/bin/stopapp.sh
stopapp.sh: Stopping app
stopapp.sh: Done
installapp.shz: Extracting archive directory 'app' in '/myapp/distrib'
installapp.shz: Executing command: app/bin/setup.sh --register myhost
config.sh: Configuring app
config.sh: Starting app