Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Package tar.gz into a shell script

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

like image 915
Da Ma Avatar asked Dec 19 '22 05:12

Da Ma


2 Answers

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
like image 144
Randall Cook Avatar answered Dec 21 '22 17:12

Randall Cook


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.

like image 45
Jahid Avatar answered Dec 21 '22 18:12

Jahid