Source string Read only

(itstool) path: callout/screen

246/2460
Context English State
When the system is going to shut down, <filename>/etc/rc.shutdown</filename> runs. It assumes that most <filename>rc.d</filename> scripts have nothing to do at that time. Therefore <filename>/etc/rc.shutdown</filename> selectively invokes <filename>rc.d</filename> scripts with the <literal>shutdown</literal> keyword, effectively ignoring the rest of the scripts. For even faster shutdown, <filename>/etc/rc.shutdown</filename> passes the <option>faststop</option> command to the scripts it runs so that they skip preliminary checks, e.g., the pidfile check. As dependent services should be stopped before their prerequisites, <filename>/etc/rc.shutdown</filename> runs the scripts in reverse dependency order.
If writing a real <filename>rc.d</filename> script, you should consider whether it is relevant at system shutdown time. E.g., if your script does its work in response to the <option>start</option> command only, then you need not include this keyword. However, if your script manages a service, it is probably a good idea to stop it before the system proceeds to the final stage of its shutdown sequence described in <citerefentry><refentrytitle>halt</refentrytitle><manvolnum>8</manvolnum></citerefentry>. In particular, a service should be stopped explicitly if it needs considerable time or special actions to shut down cleanly. A typical example of such a service is a database engine.
<anchor xml:id="forcedep"/>To begin with, <function>force_depend</function> should be used with much care. It is generally better to revise the hierarchy of configuration variables for your <filename>rc.d</filename> scripts if they are interdependent.
If you still cannot do without <function>force_depend</function>, the example offers an idiom of how to invoke it conditionally. In the example, our <command>mumbled</command> daemon requires that another one, <command>frotz</command>, be started in advance. However, <command>frotz</command> is optional, too; and <citerefentry><refentrytitle>rcorder</refentrytitle><manvolnum>8</manvolnum></citerefentry> knows nothing about such details. Fortunately, our script has access to all <citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> variables. If <envar>frotz_enable</envar> is true, we hope for the best and rely on <filename>rc.d</filename> to have started <command>frotz</command>. Otherwise we forcibly check the status of <command>frotz</command>. Finally, we enforce our dependency on <command>frotz</command> if it is found to be not running. A warning message will be emitted by <function>force_depend</function> because it should be invoked only if a misconfiguration has been detected.
Giving more flexibility to an rc.d script
When invoked during startup or shutdown, an <filename>rc.d</filename> script is supposed to act on the entire subsystem it is responsible for. E.g., <filename>/etc/rc.d/netif</filename> should start or stop all network interfaces described by <citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>. Either task can be uniquely indicated by a single command argument such as <option>start</option> or <option>stop</option>. Between startup and shutdown, <filename>rc.d</filename> scripts help the admin to control the running system, and it is when the need for more flexibility and precision arises. For instance, the admin may want to add the settings of a new network interface to <citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> and then to start it without interfering with the operation of the existing interfaces. Next time the admin may need to shut down a single network interface. In the spirit of the command line, the respective <filename>rc.d</filename> script calls for an extra argument, the interface name.
Fortunately, <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> allows for passing any number of arguments to script's methods (within the system limits). Due to that, the changes in the script itself can be minimal.
How can <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> gain access to the extra command-line arguments. Should it just grab them directly? Not by any means. Firstly, an <citerefentry><refentrytitle>sh</refentrytitle><manvolnum>1</manvolnum></citerefentry> function has no access to the positional parameters of its caller, but <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> is just a sack of such functions. Secondly, the good manner of <filename>rc.d</filename> dictates that it is for the main script to decide which arguments are to be passed to its methods.
So the approach adopted by <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry> is as follows: <function>run_rc_command</function> passes on all its arguments but the first one to the respective method verbatim. The first, omitted, argument is the name of the method itself: <option>start</option>, <option>stop</option>, etc. It will be shifted out by <function>run_rc_command</function>, so what is <envar>$2</envar> in the original command line will be presented as <envar>$1</envar> to the method, and so on.
To illustrate this opportunity, let us modify the primitive dummy script so that its messages depend on the additional arguments supplied. Here we go:
#!/bin/sh

. /etc/rc.subr

name="dummy"
start_cmd="${name}_start"
stop_cmd=":"
kiss_cmd="${name}_kiss"
extra_commands="kiss"

dummy_start()
{
if [ $# -gt 0 ]; then<co xml:id="rcng-args-start"/>
echo "Greeting message: $*"
else
echo "Nothing started."
fi
}

dummy_kiss()
{
echo -n "A ghost gives you a kiss"
if [ $# -gt 0 ]; then<co xml:id="rcng-args-kiss"/>
echo -n " and whispers: $*"
fi
case "$*" in
*[.!?])
echo
;;
*)
echo .
;;
esac
}

load_rc_config $name
run_rc_command "$@"<co xml:id="rcng-args-all"/>
What essential changes can we notice in the script?
All arguments you type after <option>start</option> can end up as positional parameters to the respective method. We can use them in any way according to our task, skills, and fancy. In the current example, we just pass all of them to <citerefentry><refentrytitle>echo</refentrytitle><manvolnum>1</manvolnum></citerefentry> as one string in the next line — note <envar>$*</envar> within the double quotes. Here is how the script can be invoked now:
<prompt>#</prompt> <userinput>/etc/rc.d/dummy start</userinput>
Nothing started.
<prompt>#</prompt> <userinput>/etc/rc.d/dummy start Hello world!</userinput>
Greeting message: Hello world!
The same applies to any method our script provides, not only to a standard one. We have added a custom method named <option>kiss</option>, and it can take advantage of the extra arguments not less than <option>start</option> does. E.g.:
<prompt>#</prompt> <userinput>/etc/rc.d/dummy kiss</userinput>
A ghost gives you a kiss.
<prompt>#</prompt> <userinput>/etc/rc.d/dummy kiss Once I was Etaoin Shrdlu...</userinput>
A ghost gives you a kiss and whispers: Once I was Etaoin Shrdlu...
If we want just to pass all extra arguments to any method, we can merely substitute <literal>"$@"</literal> for <literal>"$1"</literal> in the last line of our script, where we invoke <function>run_rc_command</function>.
An <citerefentry><refentrytitle>sh</refentrytitle><manvolnum>1</manvolnum></citerefentry> programmer ought to understand the subtle difference between <envar>$*</envar> and <envar>$@</envar> as the ways to designate all positional parameters. For its in-depth discussion, refer to a good handbook on <citerefentry><refentrytitle>sh</refentrytitle><manvolnum>1</manvolnum></citerefentry> scripting. <emphasis>Do not</emphasis> use the expressions until you fully understand them because their misuse will result in buggy and insecure scripts.
Currently <function>run_rc_command</function> may have a bug that prevents it from keeping the original boundaries between arguments. That is, arguments with embedded whitespace may not be processed correctly. The bug stems from <envar>$*</envar> misuse.
Further reading
<anchor xml:id="lukem"/><link xlink:href="http://www.mewburn.net/luke/papers/rc.d.pdf">The original article by Luke Mewburn</link> offers a general overview of <filename>rc.d</filename> and detailed rationale for its design decisions. It provides insight on the whole <filename>rc.d</filename> framework and its place in a modern BSD operating system.
<anchor xml:id="manpages"/>The manual pages <citerefentry><refentrytitle>rc</refentrytitle><manvolnum>8</manvolnum></citerefentry>, <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry>, and <citerefentry><refentrytitle>rcorder</refentrytitle><manvolnum>8</manvolnum></citerefentry> document the <filename>rc.d</filename> components in great detail. You cannot fully use the <filename>rc.d</filename> power without studying the manual pages and referring to them while writing your own scripts.
The major source of working, real-life examples is <filename>/etc/rc.d</filename> in a live system. Its contents are easy and pleasant to read because most rough corners are hidden deep in <citerefentry><refentrytitle>rc.subr</refentrytitle><manvolnum>8</manvolnum></citerefentry>. Keep in mind though that the <filename>/etc/rc.d</filename> scripts were not written by angels, so they might suffer from bugs and suboptimal design decisions. Now you can improve them!

Loading…

No matching activity found.

Browse all component changes

Things to check

Long untranslated

The string has not been translated for a long time

Reset

Ellipsis

The string uses three dots (...) instead of an ellipsis character (…)

Reset

Glossary

English English
No related strings found in the glossary.

Source information

Source string comment

(itstool) path: callout/screen

Flags
no-wrap, read-only
Source string location
article.translate.xml:1313
String age
a year ago
Source string age
a year ago
Translation file
articles/rc-scripting.pot, string 149