|
|
@@ -7,14 +7,30 @@ sharxz(){
|
|
|
OUTPUT="-"
|
|
|
DEBUG=false
|
|
|
PARSE=false
|
|
|
- while getopts ":dpT:o:C:x:" opt; do
|
|
|
+ ADD_PARSER=false
|
|
|
+ KEEP=false
|
|
|
+ INTERACTIVE=false
|
|
|
+ INSTALL_DIR=""
|
|
|
+ while getopts ":dikpPI:T:o:C:x:" opt; do
|
|
|
case $opt in
|
|
|
d )
|
|
|
DEBUG=true
|
|
|
;;
|
|
|
+ i )
|
|
|
+ INTERACTIVE=true
|
|
|
+ ;;
|
|
|
+ k )
|
|
|
+ KEEP=true
|
|
|
+ ;;
|
|
|
p )
|
|
|
PARSE=true
|
|
|
;;
|
|
|
+ P )
|
|
|
+ ADD_PARSER=true
|
|
|
+ ;;
|
|
|
+ I )
|
|
|
+ INSTALL_DIR="$OPTARG"
|
|
|
+ ;;
|
|
|
T )
|
|
|
TAR_OPTIONS+=( $OPTARG )
|
|
|
;;
|
|
|
@@ -27,31 +43,51 @@ sharxz(){
|
|
|
x )
|
|
|
CMD="$OPTARG"
|
|
|
;;
|
|
|
- \? ) echo "Usage: sharxz [-dp] [-T TAR_OPTIONS] [-C chdir] [-x CMD] path" 1>&2
|
|
|
+ \? ) cat 1>&2 <<'USAGEEOF'
|
|
|
+
|
|
|
+Usage: sharxz [-dikp] [-I INSTALL_DIR] [-T TAR_OPTIONS] [-C CHRDIR] [-x CMD] INFILE
|
|
|
+-d DEGUG
|
|
|
+-i Interactive mode
|
|
|
+-k Keep Install Directory after exit
|
|
|
+-p Parse .sharxz contents (env, excluded)
|
|
|
+-P Add Parser to sharxz (for unpack settings, pass args after --)
|
|
|
+-T Options passed on to "tar c $TAR_OPTIONS"
|
|
|
+-I Preset Install Directory
|
|
|
+-C change directory to CHDIR, defaults to parent of INFILE
|
|
|
+-X execute CMD instead of INFILE after unpacking
|
|
|
+INFILE file to be executed on unpack.
|
|
|
+
|
|
|
+USAGEEOF
|
|
|
+ exit 1
|
|
|
;;
|
|
|
: )
|
|
|
echo "Invalid option: $OPTARG requires an argument" 1>&2
|
|
|
+ exit 1
|
|
|
;;
|
|
|
esac
|
|
|
done
|
|
|
shift $((OPTIND -1))
|
|
|
- [ "$OUTPUT" == "-" ] && OUTPUT="/dev/stdout"
|
|
|
INFILE=$1
|
|
|
+ [ "$2" != "" ] && OUTPUT="$2"
|
|
|
+ [ "$OUTPUT" == "-" ] && OUTPUT="/dev/stdout"
|
|
|
|
|
|
[ "$CHDIR" == "" ] && [ -d "$INFILE" ] &&
|
|
|
CHDIR="$INFILE"
|
|
|
[ "$CHDIR" == "" ] &&
|
|
|
CHDIR="$(dirname $INFILE)"
|
|
|
|
|
|
- [ ! -f "$INFILE" ] &&
|
|
|
- [ ! -d "$CHDIR" ] && echo "Error: $INFILE is not a file, and $CHDIR is not a directory" 1>&2 && exit 1
|
|
|
+ [ ! -f "$INFILE" ] && [ ! -d "$CHDIR" ] &&
|
|
|
+ echo "Error: INFILE: $INFILE is not a file, and CHDIR: $CHDIR is not a directory" 1>&2 && exit 1
|
|
|
|
|
|
+ [ -z "$CMD" ] && [ ! -f "$INFILE" ] &&
|
|
|
+ echo "Error: $INFILE is not a file, and no CMD was given" 1>&2 && exit 1
|
|
|
[ -z "$CMD" ] &&
|
|
|
CMD="./$(realpath "--relative-to=$CHDIR" "$INFILE")"
|
|
|
|
|
|
$DEBUG && echo "CMD: $CMD" 1>&2
|
|
|
|
|
|
{
|
|
|
+ MYPWD="$PWD"
|
|
|
cd "$CHDIR"
|
|
|
|
|
|
$DEBUG && du -sh . 1>&2
|
|
|
@@ -59,7 +95,9 @@ sharxz(){
|
|
|
$PARSE && parse_options
|
|
|
|
|
|
print_shar "$INFILE"
|
|
|
+ cd "$MYPWD"
|
|
|
} > "$OUTPUT"
|
|
|
+ [[ "$OUTPUT" == "~/dev" ]] || chmod +x "$OUTPUT"
|
|
|
|
|
|
}
|
|
|
|
|
|
@@ -75,15 +113,21 @@ parse_options(){
|
|
|
}
|
|
|
|
|
|
print_shar(){
|
|
|
- printf -- "#!/usr/bin/env bash\n\nDEBUG=$DEBUG\n"
|
|
|
- printf -- "$UNSHAR\n"
|
|
|
+ printf -- "#!/usr/bin/env bash\n\n"
|
|
|
+ printf -- "DEBUG=$DEBUG\n"
|
|
|
+ printf -- "INSTALL_DIR=\"$INSTALL_DIR\"\n"
|
|
|
+ printf -- "KEEP=$KEEP\n"
|
|
|
+ printf -- "INTERACTIVE=$INTERACTIVE\n"
|
|
|
+ $ADD_PARSER && printf -- "$SHARPARSER\n"
|
|
|
+ printf -- "$PREPSHAR\n\n"
|
|
|
+ printf -- "$UNSHAR\n\n"
|
|
|
$DEBUG && pwd 1>&2
|
|
|
$DEBUG && set -x
|
|
|
tar -c ${TAR_OPTIONS[@]} .| xz -c -3 -T 0 | base64 -w 0
|
|
|
$DEBUG && set +x
|
|
|
printf -- "\n$SETUPSHAR\n"
|
|
|
|
|
|
- printf -- "$CMD"' $@'"\n"
|
|
|
+ printf -- "$CMD"' "$@"'"\n"
|
|
|
|
|
|
printf -- "\n$CLEANUPSHAR\n"
|
|
|
|
|
|
@@ -99,42 +143,79 @@ trim() {
|
|
|
}
|
|
|
|
|
|
|
|
|
-read -r -d '' UNSHAR <<'UNSHAREOF'
|
|
|
-
|
|
|
+read -r -d '' SHARPARSER <<'SHARPARSEREOF'
|
|
|
+while getopts ":diI:-" opt; do
|
|
|
+ case $opt in
|
|
|
+ d )
|
|
|
+ DEBUG=true
|
|
|
+ ;;
|
|
|
+ i )
|
|
|
+ INTERACTIVE=true
|
|
|
+ ;;
|
|
|
+ I )
|
|
|
+ INSTALL_DIR="$OPTARG"
|
|
|
+ ;;
|
|
|
+ - )
|
|
|
+ break
|
|
|
+ ;;
|
|
|
+ \? ) cat 1>&2 <<'USAGEEOF'
|
|
|
+
|
|
|
+Usage: <sharxz> [-di] [-I INSTALL_DIR]
|
|
|
+-d DEGUG
|
|
|
+-i Interactive mode
|
|
|
+-I Preset Install Directory
|
|
|
+-- stop parsing and pass remaining arguments
|
|
|
+
|
|
|
+USAGEEOF
|
|
|
+ exit 1
|
|
|
+ ;;
|
|
|
+ : )
|
|
|
+ echo "Invalid option: $OPTARG requires an argument" 1>&2
|
|
|
+ exit 1
|
|
|
+ ;;
|
|
|
+ esac
|
|
|
+done
|
|
|
+shift $((OPTIND -1))
|
|
|
+SHARPARSEREOF
|
|
|
+
|
|
|
+read -r -d '' PREPSHAR <<'PREPSHAREOF'
|
|
|
set -e
|
|
|
$DEBUG && set -x
|
|
|
|
|
|
cleanup(){
|
|
|
+ EXITCODE=$?
|
|
|
rm -f "$FIFO_NAME"
|
|
|
- rm -r "$TMPDIR"
|
|
|
- exit 127
|
|
|
+ $KEEP || rm -r "$INSTALL_DIR"
|
|
|
+ exit $EXITCODE
|
|
|
}
|
|
|
|
|
|
FIFO_NAME=$(mktemp -u).fifo
|
|
|
mkfifo "$FIFO_NAME"
|
|
|
-TMPDIR=$(mktemp -d)
|
|
|
+[ -z "$INSTALL_DIR" ] && INSTALL_DIR="$(mktemp -d)"
|
|
|
+$INTERACTIVE && echo "INSTALL_DIR: [ $INSTALL_DIR ]" && read INSTALL_DIR
|
|
|
+[ -z "$INSTALL_DIR" ] && exit 1
|
|
|
+[ -d "$INSTALL_DIR" ] || mkdir -p "$INSTALL_DIR" || exit 1
|
|
|
|
|
|
-trap cleanup SIGINT
|
|
|
-cat $FIFO_NAME|base64 -d |xz -d -T 0 |tar -xC $TMPDIR &
|
|
|
+trap cleanup EXIT
|
|
|
+PREPSHAREOF
|
|
|
|
|
|
-cat <<SAFEPAYLOADEOF > "$FIFO_NAME"
|
|
|
+read -r -d '' UNSHAR <<'UNSHAREOF'
|
|
|
+cat "$FIFO_NAME"|base64 -d |xz -d -T 0 |tar -xC "$INSTALL_DIR" &
|
|
|
+cat <<PAYLOADEOF > "$FIFO_NAME"
|
|
|
UNSHAREOF
|
|
|
|
|
|
read -r -d '' SETUPSHAR <<'SETUPSHAREOF'
|
|
|
-SAFEPAYLOADEOF
|
|
|
+PAYLOADEOF
|
|
|
|
|
|
wait
|
|
|
rm "$FIFO_NAME"
|
|
|
-cd $TMPDIR
|
|
|
+cd "$INSTALL_DIR"
|
|
|
set +e
|
|
|
$DEBUG && pwd 1>&2
|
|
|
|
|
|
SETUPSHAREOF
|
|
|
|
|
|
read -r -d '' CLEANUPSHAR <<'CLEANUPSHAREOF'
|
|
|
-EXITCODE=$?
|
|
|
-cleanup
|
|
|
-exit $EXITCODE
|
|
|
|
|
|
CLEANUPSHAREOF
|
|
|
|