The translation is temporarily closed for contributions due to maintenance, please come back later.

Source string Read only

(itstool) path: note/para
Context English State
Now it is the right time to choose a unique name for our script once and for all. We will use it in a number of places while developing the script. For a start, let us give the same name to the script file, too.
The current style of <filename>rc.d</filename> scripting is to enclose values assigned to variables in double quotes. Keep in mind that it is just a style issue that may not always be applicable. You can safely omit quotes from around simple words without <citerefentry><refentrytitle>sh</refentrytitle><manvolnum>1</manvolnum></citerefentry> metacharacters in them, while in certain cases you will need single quotes to prevent any interpretation of the value by <citerefentry><refentrytitle>sh</refentrytitle><manvolnum>1</manvolnum></citerefentry>. A programmer should be able to tell the language syntax from style conventions and use both of them wisely.
The main idea behind <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> is that an <filename>rc.d</filename> script provides handlers, or methods, for <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> to invoke. In particular, <option>start</option>, <option>stop</option>, and other arguments to an <filename>rc.d</filename> script are handled this way. A method is a <citerefentry><refentrytitle>sh</refentrytitle><manvolnum>1</manvolnum></citerefentry> expression stored in a variable named <envar><replaceable>argument</replaceable>_cmd</envar>, where <replaceable>argument</replaceable> corresponds to what can be specified on the script's command line. We will see later how <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> provides default methods for the standard arguments.
To make the code in <filename>rc.d</filename> more uniform, it is common to use <envar>${name}</envar> wherever appropriate. Thus a number of lines can be just copied from one script to another.
We should keep in mind that <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> provides default methods for the standard arguments. Consequently, we must override a standard method with a no-op <citerefentry><refentrytitle>sh</refentrytitle><manvolnum>1</manvolnum></citerefentry> expression if we want it to do nothing.
The body of a sophisticated method can be implemented as a function. It is a good idea to make the function name meaningful.
It is strongly recommended to add the prefix <envar>${name}</envar> to the names of all functions defined in our script so they never clash with the functions from <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> or another common include file.
This call to <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> loads <citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> variables. Our script makes no use of them yet, but it still is recommended to load <citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> because there can be <citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> variables controlling <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> itself.
Usually this is the last command in an <filename>rc.d</filename> script. It invokes the <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> machinery to perform the requested action using the variables and methods our script has provided.
A configurable dummy script
Now let us add some controls to our dummy script. As you may know, <filename>rc.d</filename> scripts are controlled with <citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>. Fortunately, <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> hides all the complications from us. The following script uses <citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> via <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> 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 <filename>rc.d</filename> script can just support enabling and disabling its service. On the other hand, a mandatory <filename>rc.d</filename> script can have configuration variables. We will do both things in the same script though:

. /etc/rc.subr

rcvar=dummy_enable<co xml:id="rcng-confdummy-rcvar"/>


load_rc_config $name<co xml:id="rcng-confdummy-loadconfig"/>
: ${dummy_enable:=no} <co xml:id="rcng-confdummy-enable"/>
: ${dummy_msg="Nothing started."}<co xml:id="rcng-confdummy-opt"/>

echo "$dummy_msg"<co xml:id="rcng-confdummy-msg"/>

run_rc_command "$1"
What changed in this example?
The variable <envar>rcvar</envar> specifies the name of the ON/OFF knob variable.
Now <function>load_rc_config</function> is invoked earlier in the script, before any <citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> variables are accessed.
While examining <filename>rc.d</filename> scripts, keep in mind that <citerefentry><refentrytitle>sh</refentrytitle><manvolnum>1</manvolnum></citerefentry> defers the evaluation of expressions in a function until the latter is called. Therefore it is not an error to invoke <function>load_rc_config</function> as late as just before <function>run_rc_command</function> and still access <citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> variables from the method functions exported to <function>run_rc_command</function>. This is because the method functions are to be called by <function>run_rc_command</function>, which is invoked <emphasis>after</emphasis> <function>load_rc_config</function>.
A warning will be emitted by <function>run_rc_command</function> if <envar>rcvar</envar> itself is set, but the indicated knob variable is unset. If your <filename>rc.d</filename> script is for the base system, you should add a default setting for the knob to <filename>/etc/defaults/rc.conf</filename> and document it in <citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>. Otherwise it is your script that should provide a default setting for the knob. The canonical approach to the latter case is shown in the example.
You can make <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> act as though the knob is set to <literal>ON</literal>, irrespective of its current setting, by prefixing the argument to the script with <literal>one</literal> or <literal>force</literal>, as in <option>onestart</option> or <option>forcestop</option>. Keep in mind though that <literal>force</literal> has other dangerous effects we will touch upon below, while <literal>one</literal> just overrides the ON/OFF knob. E.g., assume that <envar>dummy_enable</envar> is <literal>OFF</literal>. The following command will run the <option>start</option> method in spite of the setting:
<prompt>#</prompt> <userinput>/etc/rc.d/dummy onestart</userinput>
Now the message to be shown at boot time is no longer hard-coded in the script. It is specified by an <citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> variable named <envar>dummy_msg</envar>. This is a trivial example of how <citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> variables can control an <filename>rc.d</filename> script.
The names of all <citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> variables used exclusively by our script <emphasis>must</emphasis> have the same prefix: <envar>${name}_</envar>. For example: <envar>dummy_mode</envar>, <envar>dummy_state_file</envar>, and so on.
While it is possible to use a shorter name internally, e.g., just <envar>msg</envar>, adding the unique prefix <envar>${name}_</envar> to all global names introduced by our script will save us from possible collisions with the <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> namespace.
As a rule, <filename>rc.d</filename> scripts of the base system need not provide defaults for their <citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> variables because the defaults should be set in <filename>/etc/defaults/rc.conf</filename> instead. On the other hand, <filename>rc.d</filename> scripts for ports should provide the defaults as shown in the example.
Here we use <envar>dummy_msg</envar> to actually control our script, i.e., to emit a variable message. Use of a shell function is overkill here, since it only runs a single command; an equally valid alternative is:
start_cmd="echo \"$dummy_msg\""
Startup and shutdown of a simple daemon
We said earlier that <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> could provide default methods. Obviously, such defaults cannot be too general. They are suited for the common case of starting and shutting down a simple daemon program. Let us assume now that we need to write an <filename>rc.d</filename> script for such a daemon called <command>mumbled</command>. Here it is:

. /etc/rc.subr


command="/usr/sbin/${name}"<co xml:id="rcng-daemon-basic-cmd"/>

load_rc_config $name
run_rc_command "$1"
Pleasingly simple, isn't it? Let us examine our little script. The only new thing to note is as follows:
The <envar>command</envar> variable is meaningful to <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry>. If it is set, <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> will act according to the scenario of serving a conventional daemon. In particular, the default methods will be provided for such arguments: <option>start</option>, <option>stop</option>, <option>restart</option>, <option>poll</option>, and <option>status</option>.
The daemon will be started by running <envar>$command</envar> with command-line flags specified by <envar>$mumbled_flags</envar>. Thus all the input data for the default <option>start</option> method are available in the variables set by our script. Unlike <option>start</option>, other methods may require additional information about the process started. For instance, <option>stop</option> must know the PID of the process to terminate it. In the present case, <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> will scan through the list of all processes, looking for a process with its name equal to <envar>$procname</envar>. The latter is another variable of meaning to <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry>, and its value defaults to that of <envar>command</envar>. In other words, when we set <envar>command</envar>, <envar>procname</envar> is effectively set to the same value. This enables our script to kill the daemon and to check if it is running in the first place.


No matching activity found.

Browse all component changes

Source information

Source string comment
(itstool) path: note/para
Source string location
String age
a year ago
Source string age
a year ago
Translation file
articles/rc-scripting.pot, string 53