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

Source string Read only

(itstool) path: callout/para
Context English State
<anchor xml:id="name-var"/>The mandatory variable <envar>name</envar> specifies the name of our script. It is required by <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry>. That is, each <filename>rc.d</filename> script <emphasis>must</emphasis> set <envar>name</envar> before it calls <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> functions.
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:
#!/bin/sh

. /etc/rc.subr

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

start_cmd="${name}_start"
stop_cmd=":"

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"/>

dummy_start()
{
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:
#!/bin/sh

. /etc/rc.subr

name=mumbled
rcvar=mumbled_enable

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

Loading…

No matching activity found.

Browse all component changes

Source information

Source string comment
(itstool) path: callout/para
Flags
read-only
Source string location
article.translate.xml:419
String age
a year ago
Source string age
a year ago
Translation file
articles/rc-scripting.pot, string 52