Script zum Erstellen einer bootfähigen SuSE FTP DVD für die Bash! unter Linux

Leider ist das Script nicht perfekt, insbesondere das Überprüfen und Nachladen von fehlerhaft heruntergeladenen Dateien funktioniert bei mir nicht. Daher müssen bestimmte Aufrufe unten unter "Main" ggfs. auskommentiert werden. Das Herunterladen selbst und das Erstellen der ISO funktioniert aber gut. Das Script stammt aus einer Linux-Mailing-Liste. Wer kann es perfektionieren und den Code zum Überprüfen der heruntergeladeten Dateien durchsehen?

Wer die DVD lieber unter Windows erstellen möchte, der findet die Anleitung hier: ../DvdPerFtpWindows.

Wer keinen DVD-Brenner zur Hand hat, findet eine Anleitung zur Installation von der Festplatte unter ../InstallationPerFestplatte.

#
# Make a bootable DVD ISO from a FTP version of SuSE Linux
#
# Dieses Script funktioniert noch nicht perfekt. Daher geniesst es mit Vorsicht. 
# Insbesondere das Überprüfen der Dateigrössen bleibt beim i586-Ordner hängen.
# Deshalb kommentiert unten am Ende der Datei in der Routine "Main" bei Bedarf
# den Call zur Subroutine CHECK mit einer Raute "#" aus.
# Ihr müsst dieses Script als "root" ausführen, es sei denn, Ihr habt schon
# Schreibrechte in /srv/ftp für Euch eingeräumt. Ebenfalls solltet Ihr die
# Pfadangaben in "Programs and Paths" überprüfen, ob alle Pfadangaben richtig
# sind. Momentan funktioniert dieses Script unter SuSE 8.2 gut (mit Ausnahme
# der CHECK-Routine)
#

# Change according to your needs 
VER=9.0
DIR="/srv/ftp/pub/suse/i386/$VER"
ISODIR="/srv/ftp/pub/cdlibrary/iso"
ISO="SuSE-${VER}-ftp.iso"
TMPDIR="/tmp"
MD5SUM_ER_FILE="md5sumerror"
LS_FILE="ls_for_dir"

# Programs and paths
WGETBIN=/usr/bin/wget
PINGBIN=/bin/ping
GREPBIN=/usr/bin/grep
RMBIN=/bin/rm
TOUCHBIN=/usr/bin/touch
FINDBIN=/usr/bin/find
PSBIN=/bin/ps
PWDBIN=/bin/pwd 
MD5SUMBIN=/usr/bin/md5sum
MKISOFSBIN=/usr/local/bin/mkisofs
CUTBIN=/usr/bin/cut
SLEEPBIN=/bin/sleep
DOS2UNIXBIN=/usr/bin/dos2unix
LSBIN=/bin/ls
WCBIN=/usr/bin/wc


# You shouldn't need to change anything below this
SOURCE="$DIR/suse/src"
OPTS="-r -J -l -D -L -V  -P  -p  -abstract  -biblio -copyright"
BOOTDIR="boot/loader"
BOOT="isolinux.bin"
CAT="boot.cat"
BOPTS="-no-emul-boot -boot-load-size 4 -boot-info-table"
GRAFT="-graft-points /=$DIR"

declare -i PING
declare -i LOWPING 
declare -a LS_FILE_ARRAY
declare -a LS_LEN_ARRAY

#### FUNCTIONS ####

# Choose Mirror  
PING_MIRRORS () {
        echo "Looking for closest mirror"
        LIST="ftp-linux.cc.gatech.edu mirror.mcs.anl.gov ftp.gwdg.de
chuck.ucs.indiana.edu distro.ibiblio.org mirrors.usc.edu ftp.tu-ilmenau.de"
        let LOWPING=0
        for HOST in $LIST ; do
                PING=`eval $PINGBIN -q -c 10 $HOST | $GREPBIN rtt | $CUTBIN -d "/" -f 5 | $CUTBIN -d"." -f 1`
                echo "$HOST is $PING ms away"
                if [ "$PING" -lt  "$LOWPING" ] && [ "$PING" != "0" ] && [ "$LOWPING" != "0" ] ; then
                        LOWPING=$PING
                        PINGTEST=$HOST
                elif [ "$PING" != "0" ] && [ "$LOWPING" = "0" ] ; then
                        LOWPING=$PING
                        PINGTEST=$HOST
                fi
        done

        case $PINGTEST in
                mirrors.usc.edu)
                                MIRROR="mirrors.usc.edu"
                                MIRRORPATH="pub/linux/distributions/suse/i386/$VER"
                                ;;
                distro.ibiblio.org)
                                MIRROR="distro.ibiblio.org"
                                MIRRORPATH="pub/Linux/distributions/suse/suse/i386/$VER"
                                ;;
                ftp-linux.cc.gatech.edu)
                                MIRROR="ftp-linux.cc.gatech.edu"
                                MIRRORPATH="pub/suse/suse/i386/$VER"
                                ;;
                mirror.mcs.anl.gov)
                                MIRROR="mirror.mcs.anl.gov"
                                MIRRORPATH="pub/suse/i386/$VER"
                                ;;
                ftp.gwdg.de)
                                MIRROR="ftp.gwdg.de"
                                MIRRORPATH="pub/linux/suse/ftp.suse.com/suse/i386/$VER"
                                ;;
                chuck.ucs.indiana.edu)
                                MIRROR="chuck.ucs.indiana.edu"
                                MIRRORPATH="linux/suse/suse/i386/$VER"
                                ;;
                ftp.tu-ilmenau.de)
                                MIRROR="ftp.tu-ilmenau.de"
                                MIRRORPATH="/Mirrors/ftp.suse.com/i386/$VER"
                                ;;              
        esac

        # Don't get source rpms as they won't fit on the DVD anyway
        EXCLUDESRC="$MIRRORPATH/suse/src"

        # Cut the directories in MIRRORPATH for the ftp mirror of MIRROR
        DIRCUT=`echo ${MIRRORPATH//[A-Za-z0-9\_\.\:\\\,\-]} | $WCBIN -c`
        echo ""
}

# Test to see if the SuSE version is available
TEST_DIR () {
        echo "Testing for $VER on $MIRROR"
        eval $WGETBIN -q  -O - ftp://$MIRROR/$MIRRORPATH/ >/dev/null
        NEWTEST=$?
}

# Exit if the SuSE version wanted isn't available
MIRROR () {
        if [ "$NEWTEST" = 0 ] ; then
                echo "OK" 
                echo ""
                echo "Mirroring $MIRROR"
                eval $WGETBIN -cmq -nH --passive -X /$EXCLUDESRC -P $DIR --cut-dirs=${DIRCUT// } ftp://${MIRROR}/${MIRRORPATH} & 
                PID=$!
                while true ; do
                        RUNNING=`eval $PSBIN h -o pid  -p $PID`
                        if [ "${RUNNING}" ] ; then
                                echo -en "#"
                                eval $SLEEPBIN 5
                        else
                                echo "#"
                                echo "Download complete"
                                echo ""
                                break
                        fi
                done
        else
                echo "$VER isn't avialable"
                exit 1
        fi
}

#Verify file sizes
CHECK () {
        for DOTLIST in `eval $FINDBIN $DIR -name "\.listing"` ; do
                eval $DOS2UNIXBIN -q $DOTLIST   
                eval $LSBIN -l ${DOTLIST%.*} | $GREPBIN -v total > $TMPDIR/$LS_FILE
                cd ${DOTLIST%.*}
                NAME=${DOTLIST%.*}
                PATH=${NAME//$DIR}
                unset LS_FILE_ARRAY
                unset LS_LEN_ARRAY
                let x=0
                while read x1 x2 x3 x4 LEN x5 x6 x7 FILE ; do 
                        if [ ! -d "$FILE" ] ; then 
                                LS_FILE_ARRAY["$x"]="$FILE"
                                LS_LEN_ARRAY["$x"]="$LEN"
                                let x++
                        fi      
                done < $TMPDIR/$LS_FILE
                COUNT=${#LS_FILE_ARRAY[@]}
                if [ $COUNT -gt 0 ] ; then
                        echo ""
                        echo "Looking at file sizes in ${DOTLIST%.*} -- $COUNT files"
                fi
                while read x1 x2 x3 x4 LEN x5 x6 x7 FILE ; do 
                        if [ ! -d "$FILE" ] ; then 
                                if [ -e "$FILE" ] ; then
                                        let z=0
                                        while [ $z -lt "$COUNT" ] ; do
                                                if [ "${FILE}" = "${LS_FILE_ARRAY["$z"]}" ] ; then
                                                        echo -en "#" 
                                                        if [ "${LEN}" != "${LS_LEN_ARRAY["$z"]}" ] ; then
                                                                echo "#"
                                                                echo "Getting $FILE again"
                                                                eval $RMBIN $FILE
                                                                while true ; do 
                                                                        eval $WGETBIN -q ftp://$MIRROR/$MIRRORPATH/$PATH/$FILE &
                                                                        WGETTEST=$?
                                                                        PID=$! 
                                                                        while true ; do
                                                                                RUNNING=`eval $PSBIN h -o pid  -p $PID`
                                                                                if [ "${RUNNING}" ] ; then
                                                                                        echo -en "#"
                                                                                        eval $SLEEPBIN 5
                                                                                else
                                                                                        echo "#"
                                                                                        echo ""
                                                                                break
                                                                        fi      
                                                                done
                                                                        if [ "$WGETTEST" = 0 ] ; then
                                                                               echo "Continuing file check"
                                                                               break
                                                                        fi
                                                                done
                                                        fi
                                                fi
                                                let z++ 
                                        done
                                else
                                        echo ""
                                        echo "Getting $FILE again"
                                        while true ; do 
                                                eval $WGETBIN -q ftp://$MIRROR/$MIRRORPATH/$PATH/$FILE &
                                                WGETTEST=$?
                                                PID=$! 
                                                while true ; do
                                                        RUNNING=`eval $PSBIN h -o pid -p $PID`
                                                        if [ "${RUNNING}" ] ; then
                                                                echo -en "#"
                                                                eval $SLEEPBIN 5
                                                        else
                                                                echo "#"
                                                                echo ""
                                                                break
                                                        fi
                                                done
                                                if [ "$WGETTEST" = 0 ] ; then
                                                        echo "Continuing file check"
                                                        echo ""
                                                        break
                                                fi
                                        done
                                fi                              
                        fi              
                done < $DOTLIST 
                #eval $RMBIN $DOTLIST
                cd -    
        done
}

# Check MD5SUMS for rpms
TEST_MD5SUMS () {
        if [ -e $TMPDIR/$MD5SUM_ER_FILE ] ; then
                eval $RMBIN $TMPDIR/$MD5SUM_ER_FILE
                eval $TOUCHBIN $TMPDIR/$MD5SUM_ER_FILE
        fi
        cd $DIR
        echo ""
        for MD in `eval $FINDBIN $DIR -name MD5SUMS` ; do
                cd ${MD%/*}
                echo "Checking sums in ${MD%/*}"
                echo ${MD%/*} >> $TMPDIR/$MD5SUM_ER_FILE
                eval $MD5SUMBIN -c $MD 2>/dev/null | $GREPBIN FAILED  >> $TMPDIR/$MD5SUM_ER_FILE &
                PID=$! 
                while true ; do
                        RUNNING=`eval $PSBIN h -o pid  -p $PID`
                        if [ "${RUNNING}" ] ; then
                                echo -en "#"
                                eval $SLEEPBIN 5
                        else
                                echo "#"
                                echo ""
                                break
                        fi
                done
        done
        cd -
}

# Fix md5sum errors
FIX () {
        CURRENT_DIR=`eval $PWDBIN`
        while read NAME STAT ; do
                if [ -d ${NAME} ] ; then
                        cd $NAME
                        PATH=${NAME//$DIR}
                elif [ "$STAT" = "FAILED" ] ; then 
                        echo ""
                        echo "Getting ${NAME//:} again"  
                        eval $RMBIN ${NAME//:}
                        while true ; do
                                eval $WGETBIN -q ftp://$MIRROR/$MIRRORPATH/$PATH/${NAME//:} &
                                WGETTEST=$?
                                PID=$! 
                                while true ; do
                                        RUNNING=`eval $PSBIN h -o pid  -p $PID`
                                        if [ "${RUNNING}" ] ; then
                                                echo -en "#"
                                                eval $SLEEPBIN 5
                                        else
                                                echo "#"
                                                echo ""
                                                break
                                        fi
                                done
                                if [ "$WGETTEST" = 0 ] ; then
                                        break
                                fi
                        done
                fi
        done < $TMPDIR/$MD5SUM_ER_FILE
        cd $CURRENT_DIR
}

# Make the DVD iso or exit if it already exist
ISO () {
        if [ ! -e  ${ISODIR}/${ISO} ] ; then
                eval $MKISOFSBIN $OPTS  \
                -x $SOURCE              \
                -o ${ISODIR}/${ISO}     \
                -b ${BOOTDIR}/${BOOT}   \
                -c ${BOOTDIR}/${CAT}    \
                $BOPTS                  \
                $GRAFT
        else
                echo  ${ISODIR}/${ISO} exists
        fi
}


#### MAIN ####

clear
PING_MIRRORS
TEST_DIR
MIRROR
CHECK
echo ""
eval $RMBIN $TMPDIR/$LS_FILE
while true ; do 
        TEST_MD5SUMS
        MD5SUMTEST=`$GREPBIN "FAILED" $TMPDIR/$MD5SUM_ER_FILE`
        if [ ${#MD5SUMTEST} -gt 0 ] ; then
                echo "There were problems with the md5sums. Some files will be downloaded again."
                FIX
                echo ""
                echo "Testing md5sums again"
                echo ""
        else
                eval $RMBIN $TMPDIR/$MD5SUM_ER_FILE
                break
        fi      
done                    
ISO
exit 0

SuSE/DvdPerFtpLinux (zuletzt geändert am 2007-12-23 22:47:00 durch localhost)