Practical rc.d scripting in BSD
Prev |  | Next

# 4 A configurable dummy script

Now let us add some controls to our dummy script. As you may know, `rc.d` scripts are controlled with rc.conf(5). Fortunately, rc.subr(8) hides all the complications from us. The following script uses rc.conf(5) via rc.subr(8) to see whether it is enabled in the first place, and to fetch a message to show at boot time. These two tasks in fact are independent. On the one hand, an `rc.d` script can just support enabling and disabling its service. On the other hand, a mandatory `rc.d` script can have configuration variables. We will do both things in the same script though:

    #!/bin/sh

    . /etc/rc.subr

    name="dummy"
    rcvar=`set_rcvar`
    start_cmd="${name}_start"
    stop_cmd=":"

    load_rc_config $name
    eval "${rcvar}=\${${rcvar}:-'NO'}"
    dummy_msg=${dummy_msg:-"Nothing started."}

    dummy_start()
    {
        echo "$dummy_msg"
    }

    run_rc_command "$1"

What changed in this example?

  The variable `rcvar` specifies the name of the ON/OFF knob variable. The reason to obtain the variable name from rc.subr(8) by calling `set_rcvar` is that different operating systems adopted different conventions for it. Namely, FreeBSD sticks to the `${name}_enable` scheme while NetBSD uses just `${name}` variables in its rc.conf(5). For example, our script will be controlled by `dummy_enable` in FreeBSD and by `dummy` in NetBSD.
  Now `load_rc_config` is invoked earlier in the script, before any rc.conf(5) variables are accessed.

  > Note: While examining `rc.d` scripts, keep in mind that sh(1) defers the evaluation of expressions in a function until the latter is called. Therefore it is not an error to invoke `load_rc_config` as late as just before `run_rc_command` and still access rc.conf(5) variables from the method functions exported to `run_rc_command`. This is because the method functions are to be called by `run_rc_command`, which is invoked after `load_rc_config`.

  A warning will be emitted by `run_rc_command` if `rcvar` itself is set, but the indicated knob variable is unset. If your `rc.d` script is for the base system, you should add a default setting for the knob to `/etc/defaults/rc.conf` and document it in rc.conf(5). Otherwise it is your script that should provide a default setting for the knob. A portable approach to the latter case is shown in the example.

  > Note: You can make rc.subr(8) act as though the knob is set to `ON`, irrespective of its current setting, by prefixing the argument to the script with `one` or `force`, as in `onestart` or `forcestop`. Keep in mind though that `force` has other dangerous effects we will touch upon below, while `one` just overrides the ON/OFF knob. E.g., assume that `dummy_enable` is `OFF`. The following command will run the `start` method in spite of the setting:

  >     # /etc/rc.d/dummy onestart

  Now the message to be shown at boot time is no longer hard-coded in the script. It is specified by an rc.conf(5) variable named `dummy_msg`. This is a trivial example of how rc.conf(5) variables can control an `rc.d` script.

  > Important: The names of all rc.conf(5) variables used exclusively by our script must have the same prefix: `${name}`. For example: `dummy_mode`, `dummy_state_file`, and so on.

  > Note: While it is possible to use a shorter name internally, e.g., just `msg`, adding the unique prefix `${name}` to all global names introduced by our script will save us from possible collisions with the rc.subr(8) namespace.

  > As long as an rc.conf(5) variable and its internal equivalent are the same, we can use a more compact expression to set the default value:

  >     : ${dummy_msg:="Nothing started."}

  > The current style is to use the more verbose form though.

  > As a rule, `rc.d` scripts of the base system need not provide defaults for their rc.conf(5) variables because the defaults should be set in `/etc/defaults/rc.conf` instead. On the other hand, `rc.d` scripts for ports should provide the defaults as shown in the example.

  Here we use `dummy_msg` to actually control our script, i.e., to emit a variable message.

Prev | Home | Next
A dummy script |  | Startup and shutdown of a simple daemon

This, and other documents, can be downloaded from ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

For questions about FreeBSD, read the documentation before contacting <questions@FreeBSD.org>.
For questions about this documentation, e-mail <doc@FreeBSD.org>.