Генератор SFX архивов и инсталяторов

Материал из Linux Wiki
Перейти к: навигация, поиск

Небольшой скрипт-генератор инсталях и SFX-архивов а-ля NVidia installer. Работает в большинстве POSIX систем. Реализует внедрение и извлечение тела архива из скрипта с помощью uuencode и uudecode. Нетребователен к ресурсам. Не оптимален в размере и способе представления тела архива (если важен размер конечного архива - вам не сюда).

#!/bin/sh
#
# package.sh - tool for creating self-extracting and self-installing packages.
#
# SYNOPSIS
#
# package.sh DIR [NAME]
#       creates a package from directory DIR with name NAME
# 
# package.sh uses tar, uuencode and gzip to generate a package. It generates 
# installing and uninstalling scripts in DIR/package directory to provide
# additional flexibility for users. These files (install.sh and uninstall.sh)
# are not generated if exist.
 
generate_install_script() {
cat << EOF
#!/bin/sh
# This is a simple installer script generated by package.sh - simple self-extracting
# and self-installing package creator
 
if [ ! -d "\$PWD/package" ]; then
        echo "This script must be run from the directory where package is installed"
        exit 1
fi
 
# Basic installation routines
chown -fR \`whoami\` *
EOF
}
 
generate_uninstall_script() {
cat << EOF
#!/bin/sh
# This is a simple uninstaller script generated by package.sh - simple self-extracting
# and self-installing package creator
 
if [ ! -d "\$PWD/package" ]; then
        echo "This script must be run from the directory where package is installed"
        exit 1
fi
 
tac package/list | while read FILE
        do
        if [ -d "\$FILE" ] ; then
                rmdir \$FILE 2>/dev/null
        else
                rm \$FILE
        fi
        done
 
rmdir package
 
exit 0;
EOF
}
 
package_installer() {
cat << EOF
#!/bin/sh
#
# Package installation script. 
if [ -n "\$1" ]
then 
        if [ -d "\$1" ]
        then
                TARGETDIR="\$1"
        else
                echo "Directory does not exist" > /dev/stderr
                exit 1;
        fi
else
        echo -n "Please, specify target directory[default is \$PWD]: "
        read TARGETDIR
 
        if [ -n "." ]
        then 
                TARGETDIR="."
        else
                while [ ! -d "\$TARGETDR" ]
                do
                        echo "Directory does not exist." > /dev/stderr
                        echo -n "Please, specify target directory"
                        read TARGETDIR 
                done
        fi
fi
 
FILELIST=\`mktemp\`
echo -n "Extracting archive contents. This may take a while.."
cat \$0 | uudecode | bzip2 -dc | tar -xvkC \$TARGETDIR > \$FILELIST
 
echo "\$TARGETDIR/package/list" > \$TARGETDIR/package/list 
cat \$FILELIST >> \$TARGETDIR/package/list
rm \$FILELIST
 
echo -ne "Done.\\nRunning installation script.."
cd \$TARGETDIR
package/install.sh
 
echo -ne "Done.\nDo you want to remove the installer?(y/N) "
read ANSWER
 
if [ "\$ANSWER" == "y" ]; then 
        rm \$0;
fi
 
echo "Done. Enjoy!"
exit 0;
 
EOF
}
 
 
# The main program flow begins here.
DIR=$PWD
 
if [ -n "$1" ]
then 
        if [ -d "$1" ]
        then
                TARGETDIR="$1"
        else
                echo "Directory does not exist" > /dev/stderr
                exit 1;
        fi
else
        echo -n "Please, specify target directory[default is $PWD]: "
        read TARGETDIR
 
        if [ ! -n "$TARGETDIR" ]
        then 
                TARGETDIR="."
        else
                while [ ! -d "$TARGETDR" ]
                do
                        echo "Directory does not exist." > /dev/stderr
                        echo -n "Please, specify target directory"
                        read TARGETDIR 
                done
        fi
fi
 
# Creating scripts directory if not exist
if [ ! -d "$TARGETDIR/package" ]; then
        mkdir $TARGETDIR/package
fi
 
 
# Generating installation script if not specified by user.
INSTALLSCRIPT="$TARGETDIR/package/install.sh"
if [ ! -f "$TARGETDIR/package/install.sh" ]; then
        echo -n "Generating installer script.."
        generate_install_script > $INSTALLSCRIPT
        chmod a+x $INSTALLSCRIPT
        echo "Done."
fi
 
 
# Generating uninstallation script if not specified by user.
UNINSTALLSCRIPT="$TARGETDIR/package/uninstall.sh"
if [ ! -f "$UNINSTALLSCRIPT" ]; then
        echo -n "Generating uninstaller script.."
        generate_uninstall_script > $UNINSTALLSCRIPT
        chmod a+x $UNINSTALLSCRIPT
        echo "Done."
fi
 
echo -n "Compressing data. This may take a while.."
DATA=`mktemp`
cd $TARGETDIR
tar -cf -  . | bzip2 -9z | uuencode - > $DATA
cd $DIR
 
#Generating the final package and naming it as user desires.
echo -ne "Done.\nGenerating package.."
PACKAGE=`mktemp -p . package.sh.XXXXXXX`
package_installer > $PACKAGE
cat $DATA >> $PACKAGE
 
echo -ne "Done.\nRemoving temporary files.."
rm $DATA
 
PACKAGENAME=""
# Setting up the package name
if [ -n "$2" ]; then
        PACKAGENAME=$2
else
        PACKAGENAME="`basename $TARGETDIR`.sh"
fi
 
# If the same file is aready exist - ask user
if [ -f "$PACKAGENAME" ]; then
        echo -ne "\nFile $PACKAGENAME already exists. Overwrite?(y/N) "
        read ANSWER
        if [ "$ANSWER" != "y" ]; then
                exit 1;
        fi
else
        mv "$PACKAGE" "$PACKAGENAME"
        PACKAGE=$PACKAGENAME
fi
 
chmod a+x $PACKAGE
 
echo -e "Done.\nEnjoy!"
exit 0;