Enclosed please find code and man page of a bash+sed script that uses update-rc.d to emulate the behavior of the IRIX/Red-Hat chkconfig tool Try a few invocations with --dryrun to see exactly what it does -- that switch makes it print the generated commands rather than executing them.
Upconversion of the chkconfig.8 page to XML-DocBook is available on request, if you prefer that format. This will be useful because some third-party packages (especially in the Red Hat world) rely on chkconfig in their installation scripts. I wrote this because as a Red Hat refugee I missed chkconfig. I'm contributing this to upstart for the usual reason, which is that I'd rather not have to maintain and separately distribute it myself. Also, BTW, because I think upstart is pretty cool. I've been administering boxes with System V runlevels for literally decades, and they were OK, but I'm not sorry to see an elegant new approach displace them. Congrats on getting picked up by Debian and Ubuntu, and best wishes for total world domination. -- <a href="http://www.catb.org/~esr/">Eric S. Raymond</a>
#!/bin/bash # # chkconfig -- list, enable, and disable system services by runlevel # # By Eric S. Raymond, May 2007. Released under BSD license. # # This is an emulation of the IRIX chkconfig tool to run over Debian/Ubuntu # (it calls update-rc.d, the native tool, to do the actual work). Also # requires sed(1) and runlevel(8). # # I wrote this because (a) a significant number of third-party packages # depend on chkconfig, and (b) as an ex-Red-Hat user, I'm used to this # interface and want it handy. # Things one might want to configure RUNLEVELS="1 2 3 4 5 6 S" ONOFFDEFAULT=2345 START=20 STOP=80 currentlevel () { # Get the current run level set -- `runlevel` echo $2 } explode () { # Explode a sequence of digits into a space-separated list echo "$1" | sed -e 's/[0-9A-Z]/ &/g' } checkroot(){ # Privileged operation coming up, require caller to be superuser. if [ "$prefix" != echo -a "$EUID" -ne 0 ] then echo "chkconfig: you must be root to use this feature." exit 1 fi } parse_init_header() { # Parse an LSB INIT INFO header for default start and stop levels. { state=0 startlevels='' stoplevels='' status=1 while read line do #echo "Looking at" $line if expr "$line" : ".*BEGIN INIT INFO" >/dev/null then state=1 status=0 continue fi if expr "$line" : ".*END INIT INFO" >/dev/null then state=0 continue fi if [ $state = 1 ] then t1=`expr "$line" : '.*Default-Start:[ \t]*\(.*\)'` if [ "$t1" != "" ] then startlevels="$t1" fi t2=`expr "$line" : '.*Default-Stop:[ \t]*\(.*\)'` if [ "$t2" != "" ] then stoplevels="$t2" fi fi done } </etc/init.d/$1 return $status } clearlevels () { # Clear init scripts for $name at runlevels $* name=$1 shift for level in $*; do $prefix rm -f /etc/rc[${level}].d/[SK][0-9][0-9]$name done } chkconfig_list() { if [ $# == 0 ] then for service in /etc/init.d/* do # Ignoring files that aren't executable is a cheap way # to skip README and other similar cruft like .dpkg-dist. if [ -x $service ] then chkconfig_list `basename $service` fi done else printf "%-16s\t" $1 for i in $RUNLEVELS do status="none" # Other chkconfigs report 'off' here if [ -f /etc/rc$i.d/K[0-9][0-9]$1 ] then status=off fi if [ -f /etc/rc$i.d/S[0-9][0-9]$1 ] then status=on fi printf "$i:$status\t" done echo "" fi } chkconfig_add() { if parse_init_header $1 then exec $prefix update-rc.d $1 start $START $startlevels . stop $STOP $stoplevels . else echo "chkconfig: can't --add a service with no INIT INFO header." exit 1 fi } chkconfig_del() { exec $prefix update-rc.d -f $1 remove } chkconfig_level() { levels=$1 name=$2 directive=$3 priority=$4 if [ "$name" = "" ] then echo "chkconfig: requires a service name" exit 1 fi # Query the state of a service (doesn't require root). if [ "$directive" = "" ] then levels=${levels:-`currentlevel`} if [ -f /etc/rc${level}.d/S[0-9][0-9]${1} ] then exit 0 else exit 1 fi fi # Turn on, turn off, or reset a service. checkroot case $directive in on) levels=${levels:-$ONOFFDEFAULT} clearlevels $name $levels $prefix update-rc.d $name start ${priority:-$START} `explode $levels` . ;; off) levels=${levels:-$ONOFFDEFAULT} clearlevels $name $levels $prefix update-rc.d $name stop ${priority:-$STOP} `explode $levels` . ;; reset) if parse_init_header $name then startlevels=${startlevels:-$RESETDEFAULT} stoplevels=${stoplevels:-$RESETDEFAULT} clearlevels $name ${startlevels}${stoplevels} $prefix update-rc.d $name \ start ${priority:-$START} `explode $startlevels` . \ stop ${priority:-$STOP} `explode $stoplevels` . else echo "chkconfig: no INIT INFO header found" exit 1 fi ;; *) echo "chkconfig: unknown operation '$directive'"; exit 1 ;; esac } if [ "$#" = 0 ] then echo -en "usage: chkconfig --list [name]\n\ chkconfig [--dryrun] --add <name>\n\ chkconfig [--dryrun] --del <name>\n\ chkconfig [--dryrun] [--level <levels>] <name> [<on|off|reset>] [priority]\n" exit 0 fi prefix="" if [ "$1" = "--dryrun" ] then prefix=echo shift fi case $1 in --list) shift; chkconfig_list $1 ;; --add) checkroot; shift; chkconfig_add $1 ;; --del) checkroot; shift; chkconfig_del $1 ;; --level) shift; chkconfig_level $* ;; *) chkconfig_level "" $* ;; esac
.TH CHKCONFIG 8 "Wed Oct 8 1997" .UC 4 .SH NAME chkconfig \- updates and queries runlevel information for system services .SH SYNOPSIS \fBchkconfig\fR \fB--list\fR [\fIname\fR] .br \fBchkconfig\fR [\fB--dryrun\fR] \fB--add\fR \fIname\fR .br \fBchkconfig\fR [\fB--dryrun\fR] \fB--del\fR \fIname\fR .br \fBchkconfig\fR [\fB--dryrun\fR] [\fB--level\fR \fIlevels\fR] \fIname\fR {\fBon\fR|\fBoff\fR||\fBreset\fR\fR} [priority] .br \fBchkconfig\fR [\fB--level\fR \fIlevels\fR] \fIname\fR .br .SH DESCRIPTION \fBchkconfig\fR provides a simple command-line tool for maintaining the /etc/rc[0-6].d directory hierarchy by relieving system administrators of the task of directly manipulating the numerous symbolic links in those directories. This implementation of \fBchkconfig\fR was inspired by the \fBchkconfig\fR command present in the IRIX operating system and Red Hat Linux. Rather than maintaining configuration information outside of the /etc/rc[0-6].d hierarchy, however, this version uses update-rc.d to directly manages the symlinks in /etc/rc[0-6].d. This leaves all of the configuration information regarding what services \fIinit\fR starts in a single location. \fBchkconfig\fR has five distinct functions: adding new services for management, removing services from management, listing the current startup information for services, changing the startup information for services, and checking the startup state of a particular service. When \fBchkconfig\fR is run without any options, it displays usage information. If only a service name is given, it checks to see if the service is configured to be started in the current runlevel. If it is, \fBchkconfig\fR returns true (0); otherwise it returns false (1). The \fB--level\fR option may be used to have \fBchkconfig\fR query an alternative runlevel rather than the current one. If one of \fBon\fR, \fBoff\fR, or \fRreset\fR is specified after the service name, \fBchkconfig\fR changes the startup information for the specified service. The \fBon\fR and \fBoff\fR flags cause the service to be started or stopped, respectively, in the runlevels being changed. The \fBreset\fR flag resets the startup information for the service to whatever is specified in the init script in question. The optional priority argument, used only if the operation is \fBon\fR or\fBoff\fR, sets the start or stop priority of the link. By default, the \fBon\fR and \fBoff\fR options affect only runlevels 2, 3, 4, and 5, while \fBreset\fR affects all of the runlevels. The \fB--level\fR option may be used to specify which runlevels are affected. Note that for every service, each runlevel has either a start script or a stop script. When switching runlevels, init will not re-start an already-started service, and will not re-stop a service that is not running. .SH OPTIONS .TP \fB--dryrun\fR Show what the rest of the command line would do, but don't actually do it. .TP \fB-\-level \fIlevels\fR Specifies the run levels an operation should pertain to. It is given as a string of numbers from 0 to 7. For example, \fB--level 35\fR specifies runlevels 3 and 5. .TP \fB-\-add\fR \fIname\fR This option adds a new service for management by \fBchkconfig\fR. When a new service is added, \fBchkconfig\fR ensures that the service has either a start or a kill entry in every runlevel. If any runlevel is missing such an entry, \fBchkconfig\fR creates the appropriate entry as specified by the default values in the init script. Note that default entries in LSB-delimited 'INIT INFO' sections take precedence over the default runlevels in the initscript. .TP \fB-\-del\fR \fIname\fR The service is removed from \fBchkconfig\fR management, and any symbolic links in /etc/rc[0-6].d which pertain to it are removed. Note that future package installs for this service may run \fBchkconfig \-\-add\fR, which will re-add such links. To disable a service, run \fBchkconfig \fIname\fR \fBoff\fR. .TP \fB-\-list\fR \fIname\fR This option lists all of the services which \fBchkconfig\fR knows about, and whether they are stopped or started in each runlevel. If \fIname\fR is specified, information in only display about service \fIname\fR. .SH LIMITATIONS Red Hat \fBchkconfig\fR could manage xinetd scripts by manipulating xinetd.d configuration files (only the \fBon\fR, \fBoff\fR, and \fB-\-list\fR commands were supported for xinetd.d services). This Debian/Ubuntu port doesn't do that. Red Hat \fBchkconfig\fR had a special syntax for embedding metainformation in init-script headers which this script doesn't support. Instead, this script interprets LSB INIT INFO blocks, which are functionally equivalent except that they don't specify priority numbers. To compensate, this implementation adds the priority argument; if that is not given, the script uses a fixed startup priority of 20 and a fixed stop priority of 80, relying on processing of the dependencies in the LSIB INIT INFO blocks to get ordering right. On the other hand, the IRIX and Red Hat version didn't have --dryrun. .SH SEE ALSO .IR init (8). .IR runlevel (8). .SH AUTHOR .nf Eric S. Raymond. Portions of the manual page are from the Red Hat implementation by Erik Troan <[EMAIL PROTECTED]>. .fi
-- upstart-devel mailing list upstart-devel@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/upstart-devel