I'd like to know how to package a tar.gz file into a shell script, just like idk**.bin does. So I can deliver the program in one shell file instead of tar.gz
There is a Linux Journal article explaining how to do this in detail, with code for packing the payload, etc. As Etan Reisner says in his comment, the extraction/installation script knows how to cut its tail off to obtain the payload which was concatenated earlier. Here's an example of how that works:
#!/bin/bash
# a self-extracting script header
# this can be any preferred output directory
mkdir ./output_dir
# determine the line number of this script where the payload begins
PAYLOAD_LINE=`awk '/^__PAYLOAD_BELOW__/ {print NR + 1; exit 0; }' $0`
# use the tail command and the line number we just determined to skip
# past this leading script code and pipe the payload to tar
tail -n+$PAYLOAD_LINE $0 | tar xzv -C ./output_dir
# now we are free to run code in output_dir or do whatever we want
exit 0
# the 'exit 0' immediately above prevents this line from being executed
__PAYLOAD_BELOW__
Note the use of $0
to refer to the script itself.
To create the installer in the first place, you need to concatenate the code above and the tarball you want to install/deliver. If the script above is called extract.sh, and the payload is called payload.tar.gz, then this command would do the trick:
cat extract.sh payload.tar.gz > run_me.sh
You can do it like this too:
#!/bin/bash
BASEDIR=`dirname "${0}"`
cd "$BASEDIR"
payload=$1
script=$2
tmp=__extract__$RANDOM
[ "$payload" != "" ] || read -e -p "Enter the path of the tar archive: " payload
[ "$script" != "" ] || read -e -p "Enter the name/path of the script: " script
printf "#!/bin/bash
PAYLOAD_LINE=\`awk '/^__PAYLOAD_BELOW__/ {print NR + 1; exit 0; }' \$0\`
tail -n+\$PAYLOAD_LINE \$0 | tar -xvz
#you can add custom installation command here
exit 0
__PAYLOAD_BELOW__\n" > "$tmp"
cat "$tmp" "$payload" > "$script" && rm "$tmp"
chmod +x "$script"
If you save this file as t2s
, then you can use it like this:
t2s test.tar.gz install.sh
Running install.sh
will extract the content in the current directory. You can run custom installation scripts too if you need. You will have to add them in the printf
section properly.
If you need to do it for other compression types (.tar.bz2
etc..), you will need to edit the z
option in the section:
tail -n+\$PAYLOAD_LINE \$0 | tar xzv
#it's inside a quote and $ needs to be printed, so you will need to use \
For example:
For .tar.bz2:
tail -n+\$PAYLOAD_LINE \$0 | tar xjv
#it's inside a quote and $ needs to be printed, so you will need to use \
For .tar
tail -n+\$PAYLOAD_LINE \$0 | tar xv
#it's inside a quote and $ needs to be printed, so you will need to use \
For information on this option you can see the man page of tar:
man tar
I have made it into a tool to automate these tasks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With