January 2006

Using sed for UNIX Portability II

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.

Some General Options

There are a number of ways to approach the problem, three were tried:

  • Using uname to automatically determine the platform.
  • Make it a configurable parameter.
  • Automatically determine at 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.

Using uname

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.

Configurable Parameter

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).

Determine at Build-install

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.

Solution

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 
	echo Error! No OS or Distribution specified
	exit 1
fi

chmod 0755 $DST_FILE

exit 0

Two arguments are needed:

  • The platform name.
  • The source file.

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.

Summary

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.

 

Digg!
Submit site
news to Digg!

Slashdot Slashdot It!
Delicious Bookmark on Delicious