I have written this script to install gcc (here in version 4.9.2) on Centos6.6. I am only interested in C and C++ support.
Please comment if this is any good and can I make it better before I get the packages for those.
#!/bin/bash
LOGFILE=/tmp/gcc_install.log
# 1ドル - package name
# 2ドル - status
errorIf(){
if [ 2ドル -ne 0 ]; then
echo "Something was wrong with 1ドル"
exit 1
fi
}
################################################################################
################################# SCRIPT START #################################
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" 1>&2
exit 1
fi
# only one param - gcc's source directory absolute location
if [ $# -ne 1 ]; then
echo "Please give the gcc source directory as argument"
exit 1
fi
if [ ! -d "1ドル" ]; then
echo "gcc's source directory that you have passed doesn't exist!"
exit 1
fi
SOURCE_DIR="1ドル"
SOURCE_DIR_NAME="${SOURCE_DIR##*/}"
cd "$SOURCE_DIR"/contrib/
################################################################################
################################# gmp, mpgr, mpc ##############################
# this script assumes that you have ran download_prerequisites from gcc's contrib dir
# contrib with downloaded gmp, mpgr, mpc (used download_prerequisites)
if [ ! -d gmp ] || [ ! -d mpfr ] || [ ! -d mpc ]; then
echo "There is no gmp or mpfr or mpc directory in `pwd`. Please run download_prerequisites."
exit 1
fi
echo "Installing gcc and dependencies. You can check the status and results in $LOGFILE"
#gmp
cd gmp && ./configure --enable-shared --enable-static --prefix=/usr/local >$LOGFILE 2>&1 && make >$LOGFILE 2>&1 && make check >$LOGFILE 2>&1 && make install >$LOGFILE 2>&1 && cd ..
ret="$?"
errorIf gmp $ret
echo "gmp Installed!:)"
#mpfr
cd mpfr && ./configure --enable-shared --enable-static --prefix=/usr/local --with-gmp=/usr/local >$LOGFILE 2>&1 && make >$LOGFILE 2>&1 && make check >$LOGFILE 2>&1 && make install >$LOGFILE 2>&1 && cd ..
ret="$?"
errorIf mpfr $ret
echo "mpfr Installed!:)"
#mpc
cd mpc && ./configure --enable-shared --enable-static --prefix=/usr/local --with-gmp=/usr/local --with-mpfr=/usr/local >$LOGFILE 2>&1 && make >$LOGFILE 2>&1 && make check >$LOGFILE 2>&1 && make install >$LOGFILE 2>&1 && cd ..
ret="$?"
errorIf mpc $ret
echo "mpc Installed!:)"
echo /usr/local/lib/ >> /etc/ld.so.conf
echo /usr/local/lib64/ >> /etc/ld.so.conf
ldconfig
cd ../../
ulimit -s 32768 # for gcc tests
mkdir -p /usr/share/gdb/auto-load/usr/lib
mkdir -p gcc-build
cd gcc-build
# find mv .py command is due to this ldconfig error (gcc copies some .py files into /usr/local/lib64/)
# ldconfig: /usr/local/lib/../lib64/libstdc++.so.6.0.20-gdb.py is not an ELF file - it has the wrong magic bytes at the start.
../$SOURCE_DIR_NAME/configure --enable-shared --disable-bootstrap --with-system-zlib --enable-languages=c,c++ --enable-libgomp --enable-threads=posix --with-gmp=/usr/local --with-mpfr=/usr/local --with-mpc=/usr/local --with-fpmath=sse --disable-multilib >$LOGFILE 2>&1 && make >$LOGFILE 2>&1 && make install >$LOGFILE 2>&1 && find /usr/local/lib64 -iname "*.py" -exec mv {} /usr/share/gdb/auto-load/usr/lib/ \; >$LOGFILE 2>&1 && ldconfig >$LOGFILE 2>&1
echo "gcc from $SOURCE_DIR_NAME Installed!:)"
1 Answer 1
For the most part, your script is quite fine.
Taming the long lines
These blocks of code have some issues:
cd gmp && ./configure --enable-shared --enable-static --prefix=/usr/local >$LOGFILE 2>&1 && make >$LOGFILE 2>&1 && make check >$LOGFILE 2>&1 && make install >$LOGFILE 2>&1 && cd ..
Issues:
- The first line is too long
- It's easy to be lazy to scroll to the right
- Code that's less visible, is more error-prone, easy to overlook something
- Long lines are harder to edit in practice
- Wrapping a bunch of commands in
cd somewhere; ...; cd ..
is error prone: it's an extra mental burden to make sure that you'll end up in the right directory after the chain of commands, keeping in mind possible errors too. As much as possible, it's good to look for alternatives. - Too much repetition of
>$LOGFILE 2>&1
It would be better this way:
(
cd gmp && \
./configure --enable-shared --enable-static --prefix=/usr/local && \
make && make check && make install
) >$LOGFILE 2>&1
The (...)
is a sub-shell,
so directory changes won't affect the enclosing script.
Once the sub-shell is finished,
you'll be back in the original directory.
Grouping commands like this (also with {...}
) makes it easier to redirect all output.
I didn't break up the lines of make a b c
,
because the line was already short enough,
and quite idiomatic that way.
The exit code after the (...)
will be as you would expect,
the grouping won't affect it.
Do similarly for all the long lines.
Avoid changing directories in the middle of scripts.
When you must do, consider wrapping the relevant commands within (...)
.
Simplifying the exit code handling
The exit code handling can be simpler:
ret="$?" errorIf gmp $ret echo "gmp Installed!:)"
There's no need to save $?
in ret
.
You could use it directly.
In fact, the function can use it directly,
no need to pass it explicitly.
You can rewrite the errorIf
function like this:
errorIf() {
if [ $? -ne 0 ]; then
echo "Something was wrong with 1ドル"
exit 1
fi
}
And then simplify the exit code handling to this:
errorIf gmp
echo "gmp Installed!:)"
ShellCheck
The http://www.shellcheck.net/# website is pretty awesome. It points out a few additional issues I recommend to fix.