Explain how an rc.d script can use extra command-line arguments.
This commit is contained in:
parent
863ff33a88
commit
51a90a53d0
Notes:
svn2git
2020-12-08 03:00:23 +00:00
svn path=/head/; revision=29697
1 changed files with 138 additions and 0 deletions
|
|
@ -1164,6 +1164,144 @@ run_rc_command "$1"</programlisting>
|
|||
</calloutlist>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="rcng-args">
|
||||
<title>Giving more flexibility to an rc.d script</title>
|
||||
|
||||
<para>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 &man.rc.conf.5;. 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 &man.rc.conf.5; 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.</para>
|
||||
|
||||
<para>Fortunately, &man.rc.subr.8; 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.
|
||||
To illustrate this opportunity, let us modify the primitive
|
||||
dummy script so that its messages depend on the additional
|
||||
arguments supplied. Here we go:</para>
|
||||
|
||||
<informalexample>
|
||||
<programlisting>#!/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 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 id="rcng-args-kiss">
|
||||
echo -n " and whispers: $*"
|
||||
fi
|
||||
case "$*" in
|
||||
*[.!?])
|
||||
echo
|
||||
;;
|
||||
*)
|
||||
echo .
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
load_rc_config $name
|
||||
run_rc_command "$@"<co id="rcng-args-all"></programlisting>
|
||||
</informalexample>
|
||||
|
||||
<para>What essential changes can we notice in the script?</para>
|
||||
|
||||
<calloutlist>
|
||||
<callout arearefs="rcng-args-start">
|
||||
<para>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 &man.echo.1; as one string in the
|
||||
next line — note <envar>$*</envar> within the double
|
||||
quotes. Here is how the script can be invoked now:</para>
|
||||
|
||||
<screen>&prompt.root; <userinput>/etc/rc.d/dummy start</userinput>
|
||||
Nothing started.
|
||||
&prompt.root; <userinput>/etc/rc.d/dummy start Hello world!</userinput>
|
||||
Greeting message: Hello world!</screen>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="rcng-args-kiss">
|
||||
<para>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.:
|
||||
|
||||
<screen>&prompt.root; <userinput>/etc/rc.d/dummy kiss</userinput>
|
||||
A ghost gives you a kiss.
|
||||
&prompt.root; <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...</screen>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="rcng-args-all">
|
||||
<para>The only question left is how &man.rc.subr.8; can gain
|
||||
access to the extra command-line arguments. Should it just
|
||||
grab them directly? Not by any means. Firstly, an &man.sh.1;
|
||||
function has no access to the positional parameters of
|
||||
its caller, but &man.rc.subr.8; 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.</para>
|
||||
|
||||
<para>So the approach adopted by &man.rc.subr.8; 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.
|
||||
Consequently, 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.</para>
|
||||
|
||||
<important>
|
||||
<para>An &man.sh.1; 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 &man.sh.1; scripting. <emphasis>Do
|
||||
not</emphasis> use the expressions until you fully
|
||||
understand them because their misuse will result in
|
||||
buggy and insecure scripts.</para>
|
||||
</important>
|
||||
|
||||
<para>The <function>run_rc_command</function> function will
|
||||
consume its first argument to find the method. Hence an
|
||||
apparent shift by one argument: What is <envar>$2</envar>
|
||||
in the command line will be presented as <envar>$1</envar>
|
||||
to the method, and so on.</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="rcng-furthur">
|
||||
<title>Further reading</title>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue