January 2006
In the first part of this series, the problem of
determining what the path to rc scripts on a per platform basis
was shown within the prototype version of a service utility. Part
two of the series discusses some ways to auto-magically
take care
of that problem and the particular method used.
There are a number of ways to approach the problem, three were tried:
build-install.
The last item, build-install does not mean when the perl interpreter actually builds and executes but rather when the software is installed by a system administrator.
Initially, using the uname command seems like the best solution. The
main problem with using uname is that on Linux kernel based systems the
returned information does not specify the distribution. A Linux
distribution can also be grokked
from /etc/issue, but
doing so is dodgy at best.
Using some sort of method like an rc file or environment variable could work as well. The problem with an rc file or environment variable is the maintenance. The rc file solution means yet another config or dotfile. The problem with an environment variable is subshell lossage (which can easily occur).
The method that was chosen is to simply specify the platform right before
installing it. To facilitate specifying the platform, a helper script
was made that can be invoked from a Makefile.
Recall the line that needs to be setup:
$RC_CTL=/etc/rc.d/rc.;
Now it is set to the following along with a warning comment:
# XXX WARNING DO NOT mess with this until you look at the regex script! # This variable is set using a sed statement from the regex script. $RC_CTL=;
Next, a small sed script can be used to setup the path:
#!/bin/sh SOFT_DIST=$1 SRC_FILE=$2 DST_FILE=service if [$SOFT_DIST= slackware-linux ]; then sed/RC_CTL\=/RC_CTL\=\\/etc\/rc.d\/rc.\/$SRC_FILE > $DST_FILE elif [$SOFT_DIST= redhat-linux ]; then sed/RC_CTL\=/RC_CTL\=\\/etc\/rc.d\/init.d\/$SRC_FILE > $DST_FILE elif [$SOFT_DIST= netbsd ]; then sed/RC_CTL\=/RC_CTL\=\\/etc\/rc.d\/$SRC_FILE > $DST_FILE elif [$SOFT_DIST= hpux ]; then sed/RC_CTL\=/RC_CTL\=\\/sbin\/init.d\/$SRC_FILE > $DST_FILE elif [$SOFT_DIST= sunos ]; then sed/RC_CTL\=/RC_CTL\=\\/etc\/init.d\/$SRC_FILE > $DST_FILE else echoError! No OS or Distribution specifiedexit 1 fi chmod 0755 $DST_FILE exit 0
Two arguments are needed:
All the sed script is doing is replacing the empty part of the path
with the path to the init directory for that particular platform.
To make the entire process even easier, a simple Makefile is
used:
REGEX_SRC=platform_regex.sh
SRC=service.pl
BIN=/usr/local/bin
SRV=service
help:
@echo "To install for your platform type make target"
@echo "Targets: hpux sunos netbsd slackware-linux redhat-linux"
hpux:
sh ${REGEX_SRC} $@ ${SRC}
sunos:
sh ${REGEX_SRC} $@ ${SRC}
netbsd:
sh ${REGEX_SRC} $@ ${SRC}
slackware-linux:
sh ${REGEX_SRC} $@ ${SRC}
redhat-linux:
sh ${REGEX_SRC} $@ ${SRC}
install:
install ${SRV} ${BIN}
uninstall:
rm -v ${BIN}/${SRV}
clean:
rm -f ${SRV} *.core core
If no platform target is specified, the default will be the first target - the help target prints out the helper message:
[mui@vela:~/service-0.5$] make To install for your platform type make target Targets: hpux sunos netbsd slackware-linux redhat-linux
Note that in this particular implementation, platform versioning is not taken into account. Platform versioning can be handled as well simply by creating a new sed line for the versions and targets in the Makefile.
While sed is useful for a great many things, helper build-install scripts is definitely one place it comes in handy when dealing with different platforms. There are many build systems that have much larger (even massive in some cases) helper scripts to lend a hand.