| An interpreted script should begin with the magic
“shebang” line. That line specifies the
interpreter program for the script. Due to the shebang
line, the script can be invoked exactly like a binary
program provided that it has the execute bit set.
(See chmod(1).)
For example, a system admin can run our script manually,
from the command line: # /etc/rc.d/dummy start
Note: In order to be properly managed by the
rc.d framework, its scripts need
to be written in the sh(1) language. If you have
a service or port that uses a binary control utility
or a startup routine written in another language,
install that element in /usr/sbin
(for the system) or /usr/local/sbin
(for ports) and call it from a sh(1) script in the
appropriate rc.d directory. Tip: If you would like to learn the details of why
rc.d scripts must be written in
the sh(1) language, see how /etc/rc
invokes them by means of run_rc_script ,
then study the implementation of
run_rc_script in
/etc/rc.subr . |
| In /etc/rc.subr , a number of
sh(1) functions are defined for an rc.d
script to use. The functions are documented in
rc.subr(8). While it is theoretically possible to
write an rc.d script without ever
using rc.subr(8), its functions prove extremely handy
and make the job an order of magnitude easier. So it is
no surprise that everybody resorts to rc.subr(8) in
rc.d scripts. We are not going to
be an exception. An rc.d script must
“source” /etc/rc.subr
(include it using “. ”)
before it calls rc.subr(8)
functions so that sh(1) has an opportunity to learn
the functions. The preferred style is to source
/etc/rc.subr first of all. Note: Some useful functions related to networking
are provided by another include file,
/etc/network.subr . |
| The mandatory variable
name specifies the name of our script. It
is required by rc.subr(8). That is, each
rc.d script must
set name before it calls rc.subr(8)
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. Note: The current style of rc.d
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
sh(1) metacharacters in them, while in certain
cases you will need single quotes to prevent any
interpretation of the value by sh(1). A programmer
should be able to tell the language syntax from style
conventions and use both of them wisely. |
| The main idea behind rc.subr(8) is that an
rc.d script provides handlers, or
methods, for rc.subr(8) to invoke. In particular,
start , stop , and other
arguments to an rc.d script are
handled this way. A method is a sh(1) expression
stored in a variable named
argument _cmd ,
where argument corresponds to
what can be specified on the script's command line. We
will see later how rc.subr(8) provides default methods
for the standard arguments. Note: To make the code in rc.d more
uniform, it is common to use ${name}
wherever appropriate. Thus a number of lines can be just
copied from one script to another. |
| We should keep in mind that rc.subr(8) provides
default methods for the standard arguments. Consequently,
we must override a standard method with a no-op sh(1)
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. Important: It is strongly recommended to add the prefix
${name} to the names of all functions
defined in our script so they never clash with the
functions from rc.subr(8) or another common include
file. |
| This call to rc.subr(8) loads rc.conf(5)
variables. Our script makes no use of them yet, but it
still is recommended to load rc.conf(5) because there
can be rc.conf(5) variables controlling rc.subr(8)
itself. |
| Usually this is the last command in an
rc.d script. It invokes the
rc.subr(8) machinery to perform the requested action
using the variables and methods our script has provided. |