diff options
Diffstat (limited to 'documentation/content/en/articles/rc-scripting/_index.po')
-rw-r--r-- | documentation/content/en/articles/rc-scripting/_index.po | 1620 |
1 files changed, 1620 insertions, 0 deletions
diff --git a/documentation/content/en/articles/rc-scripting/_index.po b/documentation/content/en/articles/rc-scripting/_index.po new file mode 100644 index 0000000000..f90baeddb2 --- /dev/null +++ b/documentation/content/en/articles/rc-scripting/_index.po @@ -0,0 +1,1620 @@ +# SOME DESCRIPTIVE TITLE +# Copyright (C) YEAR The FreeBSD Project +# This file is distributed under the same license as the FreeBSD Documentation package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: FreeBSD Documentation VERSION\n" +"POT-Creation-Date: 2023-05-21 14:43-0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: YAML Front Matter: description +#: documentation/content/en/articles/rc-scripting/_index.adoc:1 +#, no-wrap +msgid "A guide to writing new rc.d scripts and understanding those already written" +msgstr "" + +#. type: Title = +#: documentation/content/en/articles/rc-scripting/_index.adoc:1 +#: documentation/content/en/articles/rc-scripting/_index.adoc:12 +#, no-wrap +msgid "Practical rc.d scripting in BSD" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:45 +msgid "Abstract" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:49 +msgid "" +"Beginners may find it difficult to relate the facts from the formal " +"documentation on the BSD [.filename]#rc.d# framework with the practical " +"tasks of [.filename]#rc.d# scripting. In this article, we consider a few " +"typical cases of increasing complexity, show [.filename]#rc.d# features " +"suited for each case, and discuss how they work. Such an examination should " +"provide reference points for further study of the design and efficient " +"application of [.filename]#rc.d#." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:51 +msgid "'''" +msgstr "" + +#. type: Title == +#: documentation/content/en/articles/rc-scripting/_index.adoc:55 +#, no-wrap +msgid "Introduction" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:61 +msgid "" +"The historical BSD had a monolithic startup script, [.filename]#/etc/rc#. " +"It was invoked by man:init[8] at system boot time and performed all userland " +"tasks required for multi-user operation: checking and mounting file systems, " +"setting up the network, starting daemons, and so on. The precise list of " +"tasks was not the same in every system; admins needed to customize it. With " +"few exceptions, [.filename]#/etc/rc# had to be modified, and true hackers " +"liked it." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:67 +msgid "" +"The real problem with the monolithic approach was that it provided no " +"control over the individual components started from [.filename]#/etc/rc#. " +"For instance, [.filename]#/etc/rc# could not restart a single daemon. The " +"system admin had to find the daemon process by hand, kill it, wait until it " +"actually exited, then browse through [.filename]#/etc/rc# for the flags, and " +"finally type the full command line to start the daemon again. The task " +"would become even more difficult and prone to errors if the service to " +"restart consisted of more than one daemon or demanded additional actions. " +"In a few words, the single script failed to fulfil what scripts are for: to " +"make the system admin's life easier." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:74 +msgid "" +"Later there was an attempt to split out some parts of [.filename]#/etc/rc# " +"for the sake of starting the most important subsystems separately. The " +"notorious example was [.filename]#/etc/netstart# to bring up networking. It " +"did allow for accessing the network from single-user mode, but it did not " +"integrate well into the automatic startup process because parts of its code " +"needed to interleave with actions essentially unrelated to networking. That " +"was why [.filename]#/etc/netstart# mutated into [.filename]#/etc/rc." +"network#. The latter was no longer an ordinary script; it comprised of " +"large, tangled man:sh[1] functions called from [.filename]#/etc/rc# at " +"different stages of system startup. However, as the startup tasks grew " +"diverse and sophisticated, the \"quasi-modular\" approach became even more " +"of a drag than the monolithic [.filename]#/etc/rc# had been." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:82 +msgid "" +"Without a clean and well-designed framework, the startup scripts had to bend " +"over backwards to satisfy the needs of rapidly developing BSD-based " +"operating systems. It became obvious at last that more steps are necessary " +"on the way to a fine-grained and extensible [.filename]#rc# system. Thus " +"BSD [.filename]#rc.d# was born. Its acknowledged fathers were Luke Mewburn " +"and the NetBSD community. Later it was imported into FreeBSD. Its name " +"refers to the location of system scripts for individual services, which is " +"in [.filename]#/etc/rc.d#. Soon we will learn about more components of the " +"[.filename]#rc.d# system and see how the individual scripts are invoked." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:93 +msgid "" +"The basic ideas behind BSD [.filename]#rc.d# are _fine modularity_ and " +"__code reuse__. _Fine modularity_ means that each basic \"service\" such as " +"a system daemon or primitive startup task gets its own man:sh[1] script able " +"to start the service, stop it, reload it, check its status. A particular " +"action is chosen by the command-line argument to the script. The [." +"filename]#/etc/rc# script still drives system startup, but now it merely " +"invokes the smaller scripts one by one with the `start` argument. It is " +"easy to perform shutdown tasks as well by running the same set of scripts " +"with the `stop` argument, which is done by [.filename]#/etc/rc.shutdown#. " +"Note how closely this follows the Unix way of having a set of small " +"specialized tools, each fulfilling its task as well as possible. _Code " +"reuse_ means that common operations are implemented as man:sh[1] functions " +"and collected in [.filename]#/etc/rc.subr#. Now a typical script can be " +"just a few lines' worth of man:sh[1] code. Finally, an important part of " +"the [.filename]#rc.d# framework is man:rcorder[8], which helps [.filename]#/" +"etc/rc# to run the small scripts orderly with respect to dependencies " +"between them. It can help [.filename]#/etc/rc.shutdown#, too, because the " +"proper order for the shutdown sequence is opposite to that of startup." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:101 +msgid "" +"The BSD [.filename]#rc.d# design is described in <<lukem, the original " +"article by Luke Mewburn>>, and the [.filename]#rc.d# components are " +"documented in great detail in <<manpages, the respective manual pages>>. " +"However, it might not appear obvious to an [.filename]#rc.d# newbie how to " +"tie the numerous bits and pieces together to create a well-styled script for " +"a particular task. Therefore this article will try a different approach to " +"describe [.filename]#rc.d#. It will show which features should be used in a " +"number of typical cases, and why. Note that this is not a how-to document " +"because our aim is not at giving ready-made recipes, but at showing a few " +"easy entrances into the [.filename]#rc.d# realm. Neither is this article a " +"replacement for the relevant manual pages. Do not hesitate to refer to them " +"for more formal and complete documentation while reading this article." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:105 +msgid "" +"There are prerequisites to understanding this article. First of all, you " +"should be familiar with the man:sh[1] scripting language to master [." +"filename]#rc.d#. In addition, you should know how the system performs " +"userland startup and shutdown tasks, which is described in man:rc[8]." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:108 +msgid "" +"This article focuses on the FreeBSD branch of [.filename]#rc.d#. " +"Nevertheless, it may be useful to NetBSD developers, too, because the two " +"branches of BSD [.filename]#rc.d# not only share the same design but also " +"stay similar in their aspects visible to script authors." +msgstr "" + +#. type: Title == +#: documentation/content/en/articles/rc-scripting/_index.adoc:110 +#, no-wrap +msgid "Outlining the task" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:114 +msgid "" +"A little consideration before starting `$EDITOR` will not hurt. To write a " +"well-tempered [.filename]#rc.d# script for a system service, we should be " +"able to answer the following questions first:" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:116 +msgid "Is the service mandatory or optional?" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:117 +msgid "" +"Will the script serve a single program, e.g., a daemon, or perform more " +"complex actions?" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:118 +msgid "Which other services will our service depend on, and vice versa?" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:120 +msgid "" +"From the examples that follow we will see why it is important to know the " +"answers to these questions." +msgstr "" + +#. type: Title == +#: documentation/content/en/articles/rc-scripting/_index.adoc:122 +#, no-wrap +msgid "A dummy script" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:125 +msgid "" +"The following script just emits a message each time the system boots up:" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:129 +#, no-wrap +msgid "#!/bin/sh <.>\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:131 +#, no-wrap +msgid ". /etc/rc.subr <.>\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:135 +#, no-wrap +msgid "" +"name=\"dummy\" <.>\n" +"start_cmd=\"${name}_start\" <.>\n" +"stop_cmd=\":\" <.>\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:140 +#, no-wrap +msgid "" +"dummy_start() <.>\n" +"{\n" +"\techo \"Nothing started.\"\n" +"}\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:143 +#, no-wrap +msgid "" +"load_rc_config $name <.>\n" +"run_rc_command \"$1\" <.>\n" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:146 +msgid "Things to note are:" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:152 +msgid "" +"➊ 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 man:chmod[1].) For example, " +"a system admin can run our script manually, from the command line:" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:156 +#, no-wrap +msgid "# /etc/rc.d/dummy start\n" +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:162 +msgid "" +"To be properly managed by the [.filename]#rc.d# framework, its scripts need " +"to be written in the man: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 [.filename]#/usr/sbin# (for the system) or " +"[.filename]#/usr/local/sbin# (for ports) and call it from a man:sh[1] script " +"in the appropriate [.filename]#rc.d# directory." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:167 +msgid "" +"If you would like to learn the details of why [.filename]#rc.d# scripts must " +"be written in the man:sh[1] language, see how [.filename]#/etc/rc# invokes " +"them by means of `run_rc_script`, then study the implementation of " +"`run_rc_script` in [.filename]#/etc/rc.subr#." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:173 +msgid "" +"➋ In [.filename]#/etc/rc.subr#, a number of man:sh[1] functions are " +"defined for an [.filename]#rc.d# script to use. The functions are " +"documented in man:rc.subr[8]. While it is theoretically possible to write " +"an [.filename]#rc.d# script without ever using man: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 man:rc.subr[8] in [.filename]#rc.d# " +"scripts. We are not going to be an exception." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:176 +msgid "" +"An [.filename]#rc.d# script must \"source\"[.filename]#/etc/rc.subr# " +"(include it using \"`.`\") _before_ it calls man:rc.subr[8] functions so " +"that man:sh[1] has an opportunity to learn the functions. The preferred " +"style is to source [.filename]#/etc/rc.subr# first of all." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:180 +msgid "" +"Some useful functions related to networking are provided by another include " +"file, [.filename]#/etc/network.subr#." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:185 +msgid "" +"➌ [[name-var]]The mandatory variable `name` specifies the name of our " +"script. It is required by man:rc.subr[8]. That is, each [.filename]#rc.d# " +"script _must_ set `name` before it calls man:rc.subr[8] functions." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:189 +msgid "" +"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." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:196 +msgid "" +"The current style of [.filename]#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 man:sh[1] metacharacters in them, while in " +"certain cases you will need single quotes to prevent any interpretation of " +"the value by man:sh[1]. A programmer should be able to tell the language " +"syntax from style conventions and use both of them wisely." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:202 +msgid "" +"➍ The main idea behind man:rc.subr[8] is that an [.filename]#rc.d# " +"script provides handlers, or methods, for man:rc.subr[8] to invoke. In " +"particular, `start`, `stop`, and other arguments to an [.filename]#rc.d# " +"script are handled this way. A method is a man: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 man:rc." +"subr[8] provides default methods for the standard arguments." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:207 +msgid "" +"To make the code in [.filename]#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." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:211 +msgid "" +"➎ We should keep in mind that man:rc.subr[8] provides default methods " +"for the standard arguments. Consequently, we must override a standard " +"method with a no-op man:sh[1] expression if we want it to do nothing." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:214 +msgid "" +"➏ The body of a sophisticated method can be implemented as a " +"function. It is a good idea to make the function name meaningful." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:218 +msgid "" +"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 " +"man:rc.subr[8] or another common include file." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:222 +msgid "" +"➐ This call to man:rc.subr[8] loads man:rc.conf[5] variables. Our " +"script makes no use of them yet, but it still is recommended to load man:rc." +"conf[5] because there can be man:rc.conf[5] variables controlling man:rc." +"subr[8] itself." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:225 +msgid "" +"➑ Usually this is the last command in an [.filename]#rc.d# script. " +"It invokes the man:rc.subr[8] machinery to perform the requested action " +"using the variables and methods our script has provided." +msgstr "" + +#. type: Title == +#: documentation/content/en/articles/rc-scripting/_index.adoc:227 +#, no-wrap +msgid "A configurable dummy script" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:237 +msgid "" +"Now let us add some controls to our dummy script. As you may know, [." +"filename]#rc.d# scripts are controlled with man:rc.conf[5]. Fortunately, " +"man:rc.subr[8] hides all the complications from us. The following script " +"uses man:rc.conf[5] via man:rc.subr[8] 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# script can " +"just support enabling and disabling its service. On the other hand, a " +"mandatory [.filename]#rc.d# script can have configuration variables. We " +"will do both things in the same script though:" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:241 +#: documentation/content/en/articles/rc-scripting/_index.adoc:332 +#: documentation/content/en/articles/rc-scripting/_index.adoc:389 +#: documentation/content/en/articles/rc-scripting/_index.adoc:621 +#: documentation/content/en/articles/rc-scripting/_index.adoc:752 +#, no-wrap +msgid "#!/bin/sh\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:243 +#: documentation/content/en/articles/rc-scripting/_index.adoc:334 +#: documentation/content/en/articles/rc-scripting/_index.adoc:391 +#: documentation/content/en/articles/rc-scripting/_index.adoc:628 +#: documentation/content/en/articles/rc-scripting/_index.adoc:754 +#, no-wrap +msgid ". /etc/rc.subr\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:246 +#, no-wrap +msgid "" +"name=dummy\n" +"rcvar=dummy_enable <.>\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:249 +#, no-wrap +msgid "" +"start_cmd=\"${name}_start\"\n" +"stop_cmd=\":\"\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:253 +#, no-wrap +msgid "" +"load_rc_config $name <.>\n" +": ${dummy_enable:=no} <.>\n" +": ${dummy_msg=\"Nothing started.\"} <.>\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:258 +#, no-wrap +msgid "" +"dummy_start()\n" +"{\n" +"\techo \"$dummy_msg\" <.>\n" +"}\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:260 +#, no-wrap +msgid "run_rc_command \"$1\"\n" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:263 +msgid "What changed in this example?" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:265 +msgid "" +"➊ The variable `rcvar` specifies the name of the ON/OFF knob variable." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:267 +msgid "" +"➋ Now `load_rc_config` is invoked earlier in the script, before any " +"man:rc.conf[5] variables are accessed." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:273 +msgid "" +"While examining [.filename]#rc.d# scripts, keep in mind that man:sh[1] " +"defers the evaluation of expressions in a function until the latter is " +"called. Therefore it is not an error to invoke `load_rc_config` as late as " +"just before `run_rc_command` and still access man:rc.conf[5] variables from " +"the method functions exported to `run_rc_command`. This is because the " +"method functions are to be called by `run_rc_command`, which is invoked " +"_after_ `load_rc_config`." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:279 +msgid "" +"➌ A warning will be emitted by `run_rc_command` if `rcvar` itself is " +"set, but the indicated knob variable is unset. If your [.filename]#rc.d# " +"script is for the base system, you should add a default setting for the knob " +"to [.filename]#/etc/defaults/rc.conf# and document it in man:rc.conf[5]. " +"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." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:286 +msgid "" +"You can make man:rc.subr[8] act as though the knob is set to `ON`, " +"irrespective of its current setting, by prefixing the argument to the script " +"with `one` or `force`, as in `onestart` or `forcestop`. Keep in mind though " +"that `force` has other dangerous effects we will touch upon below, while " +"`one` just overrides the ON/OFF knob. E.g., assume that `dummy_enable` is " +"`OFF`. The following command will run the `start` method in spite of the " +"setting:" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:290 +#, no-wrap +msgid "# /etc/rc.d/dummy onestart\n" +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:297 +msgid "" +"➍ Now the message to be shown at boot time is no longer hard-coded in " +"the script. It is specified by an man:rc.conf[5] variable named " +"`dummy_msg`. This is a trivial example of how man:rc.conf[5] variables can " +"control an [.filename]#rc.d# script." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:302 +msgid "" +"The names of all man:rc.conf[5] variables used exclusively by our script " +"_must_ have the same prefix: `${name}_`. For example: `dummy_mode`, " +"`dummy_state_file`, and so on." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:307 +msgid "" +"While it is possible to use a shorter name internally, e.g., just `msg`, " +"adding the unique prefix `${name}_` to all global names introduced by our " +"script will save us from possible collisions with the man:rc.subr[8] " +"namespace." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:310 +msgid "" +"As a rule, [.filename]#rc.d# scripts of the base system need not provide " +"defaults for their man:rc.conf[5] variables because the defaults should be " +"set in [.filename]#/etc/defaults/rc.conf# instead. On the other hand, [." +"filename]#rc.d# scripts for ports should provide the defaults as shown in " +"the example." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:314 +msgid "" +"➎ Here we use `dummy_msg` 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:" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:318 +#, no-wrap +msgid "start_cmd=\"echo \\\"$dummy_msg\\\"\"\n" +msgstr "" + +#. type: Title == +#: documentation/content/en/articles/rc-scripting/_index.adoc:321 +#, no-wrap +msgid "Startup and shutdown of a simple daemon" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:328 +msgid "" +"We said earlier that man:rc.subr[8] 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# script for such a " +"daemon called `mumbled`. Here it is:" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:337 +#: documentation/content/en/articles/rc-scripting/_index.adoc:394 +#: documentation/content/en/articles/rc-scripting/_index.adoc:631 +#, no-wrap +msgid "" +"name=mumbled\n" +"rcvar=mumbled_enable\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:339 +#, no-wrap +msgid "command=\"/usr/sbin/${name}\" <.>\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:342 +#: documentation/content/en/articles/rc-scripting/_index.adoc:440 +#: documentation/content/en/articles/rc-scripting/_index.adoc:646 +#, no-wrap +msgid "" +"load_rc_config $name\n" +"run_rc_command \"$1\"\n" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:346 +msgid "" +"Pleasingly simple, isn't it? Let us examine our little script. The only new " +"thing to note is as follows:" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:350 +msgid "" +"➊ The `command` variable is meaningful to man:rc.subr[8]. If it is " +"set, man:rc.subr[8] will act according to the scenario of serving a " +"conventional daemon. In particular, the default methods will be provided " +"for such arguments: `start`, `stop`, `restart`, `poll`, and `status`." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:359 +msgid "" +"The daemon will be started by running `$command` with command-line flags " +"specified by `$mumbled_flags`. Thus all the input data for the default " +"`start` method are available in the variables set by our script. Unlike " +"`start`, other methods may require additional information about the process " +"started. For instance, `stop` must know the PID of the process to terminate " +"it. In the present case, man:rc.subr[8] will scan through the list of all " +"processes, looking for a process with its name equal to `procname`. The " +"latter is another variable of meaning to man:rc.subr[8], and its value " +"defaults to that of `command`. In other words, when we set `command`, " +"`procname` 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." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:366 +msgid "" +"Some programs are in fact executable scripts. The system runs such a script " +"by starting its interpreter and passing the name of the script to it as a " +"command-line argument. This is reflected in the list of processes, which " +"can confuse man:rc.subr[8]. You should additionally set " +"`command_interpreter` to let man:rc.subr[8] know the actual name of the " +"process if `$command` is a script." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:371 +msgid "" +"For each [.filename]#rc.d# script, there is an optional man:rc.conf[5] " +"variable that takes precedence over `command`. Its name is constructed as " +"follows: `${name}_program`, where `name` is the mandatory variable we " +"discussed <<name-var, earlier>>. E.g., in this case it will be " +"`mumbled_program`. It is man:rc.subr[8] that arranges `${name}_program` to " +"override `command`." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:375 +msgid "" +"Of course, man:sh[1] will permit you to set `${name}_program` from man:rc." +"conf[5] or the script itself even if `command` is unset. In that case, the " +"special properties of `${name}_program` are lost, and it becomes an ordinary " +"variable your script can use for its own purposes. However, the sole use of " +"`${name}_program` is discouraged because using it together with `command` " +"became an idiom of [.filename]#rc.d# scripting." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:378 +msgid "" +"For more detailed information on default methods, refer to man:rc.subr[8]." +msgstr "" + +#. type: Title == +#: documentation/content/en/articles/rc-scripting/_index.adoc:380 +#, no-wrap +msgid "Startup and shutdown of an advanced daemon" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:385 +msgid "" +"Let us add some meat onto the bones of the previous script and make it more " +"complex and featureful. The default methods can do a good job for us, but " +"we may need some of their aspects tweaked. Now we will learn how to tune " +"the default methods to our needs." +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:397 +#, no-wrap +msgid "" +"command=\"/usr/sbin/${name}\"\n" +"command_args=\"mock arguments > /dev/null 2>&1\" <.>\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:399 +#, no-wrap +msgid "pidfile=\"/var/run/${name}.pid\" <.>\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:401 +#, no-wrap +msgid "required_files=\"/etc/${name}.conf /usr/share/misc/${name}.rules\" <.>\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:403 +#, no-wrap +msgid "sig_reload=\"USR1\" <.>\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:406 +#, no-wrap +msgid "" +"start_precmd=\"${name}_prestart\" <.>\n" +"stop_postcmd=\"echo Bye-bye\" <.>\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:408 +#, no-wrap +msgid "extra_commands=\"reload plugh xyzzy\" <.>\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:411 +#, no-wrap +msgid "" +"plugh_cmd=\"mumbled_plugh\" <.>\n" +"xyzzy_cmd=\"echo 'Nothing happens.'\"\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:432 +#, no-wrap +msgid "" +"mumbled_prestart()\n" +"{\n" +"\tif checkyesno mumbled_smart; then <.>\n" +"\t\trc_flags=\"-o smart ${rc_flags}\" <.>\n" +"\tfi\n" +"\tcase \"$mumbled_mode\" in\n" +"\tfoo)\n" +"\t\trc_flags=\"-frotz ${rc_flags}\"\n" +"\t\t;;\n" +"\tbar)\n" +"\t\trc_flags=\"-baz ${rc_flags}\"\n" +"\t\t;;\n" +"\t*)\n" +"\t\twarn \"Invalid value for mumbled_mode\" <.>\n" +"\t\treturn 1 <.>\n" +"\t\t;;\n" +"\tesac\n" +"\trun_rc_command xyzzy <.>\n" +"\treturn 0\n" +"}\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:437 +#, no-wrap +msgid "" +"mumbled_plugh() <.>\n" +"{\n" +"\techo 'A hollow voice says \"plugh\".'\n" +"}\n" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:445 +msgid "" +"➊ Additional arguments to `$command` can be passed in " +"`command_args`. They will be added to the command line after " +"`$mumbled_flags`. Since the final command line is passed to `eval` for its " +"actual execution, input and output redirections can be specified in " +"`command_args`." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:452 +msgid "" +"_Never_ include dashed options, like `-X` or `--foo`, in `command_args`. " +"The contents of `command_args` will appear at the end of the final command " +"line, hence they are likely to follow arguments present in `${name}_flags`; " +"but most commands will not recognize dashed options after ordinary " +"arguments. A better way of passing additional options to `$command` is to " +"add them to the beginning of `${name}_flags`. Another way is to modify " +"`rc_flags` <<rc-flags, as shown later>>." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:456 +msgid "" +"➋ A good-mannered daemon should create a _pidfile_ so that its " +"process can be found more easily and reliably. The variable `pidfile`, if " +"set, tells man:rc.subr[8] where it can find the pidfile for its default " +"methods to use." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:461 +msgid "" +"In fact, man:rc.subr[8] will also use the pidfile to see if the daemon is " +"already running before starting it. This check can be skipped by using the " +"`faststart` argument." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:466 +msgid "" +"➌ If the daemon cannot run unless certain files exist, just list them " +"in `required_files`, and man:rc.subr[8] will check that those files do exist " +"before starting the daemon. There also are `required_dirs` and " +"`required_vars` for directories and environment variables, respectively. " +"They all are described in detail in man:rc.subr[8]." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:470 +msgid "" +"The default method from man:rc.subr[8] can be forced to skip the " +"prerequisite checks by using `forcestart` as the argument to the script." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:476 +msgid "" +"➍ We can customize signals to send to the daemon in case they differ " +"from the well-known ones. In particular, `sig_reload` specifies the signal " +"that makes the daemon reload its configuration; it is SIGHUP by default. " +"Another signal is sent to stop the daemon process; the default is SIGTERM, " +"but this can be changed by setting `sig_stop` appropriately." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:481 +msgid "" +"The signal names should be specified to man:rc.subr[8] without the `SIG` " +"prefix, as it is shown in the example. The FreeBSD version of man:kill[1] " +"can recognize the `SIG` prefix, but the versions from other OS types may not." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:486 +msgid "" +"➎➏ Performing additional tasks before or after the default " +"methods is easy. For each command-argument supported by our script, we can " +"define `argument_precmd` and `argument_postcmd`. These man:sh[1] commands " +"are invoked before and after the respective method, as it is evident from " +"their names." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:492 +msgid "" +"Overriding a default method with a custom `argument_cmd` still does not " +"prevent us from making use of `argument_precmd` or `argument_postcmd` if we " +"need to. In particular, the former is good for checking custom, " +"sophisticated conditions that should be met before performing the command " +"itself. Using `argument_precmd` along with `argument_cmd` lets us logically " +"separate the checks from the action." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:495 +msgid "" +"Do not forget that you can cram any valid man:sh[1] expressions into the " +"methods, pre-, and post-commands you define. Just invoking a function that " +"makes the real job is a good style in most cases, but never let style limit " +"your understanding of what is going on behind the curtain." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:498 +msgid "" +"➐ If we would like to implement custom arguments, which can also be " +"thought of as _commands_ to our script, we need to list them in " +"`extra_commands` and provide methods to handle them." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:506 +msgid "" +"The `reload` command is special. On the one hand, it has a preset method in " +"man:rc.subr[8]. On the other hand, `reload` is not offered by default. The " +"reason is that not all daemons use the same reload mechanism and some have " +"nothing to reload at all. So we need to ask explicitly that the builtin " +"functionality be provided. We can do so via `extra_commands`." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:510 +msgid "" +"What do we get from the default method for `reload`? Quite often daemons " +"reload their configuration upon reception of a signal - typically, SIGHUP. " +"Therefore man:rc.subr[8] attempts to reload the daemon by sending a signal " +"to it. The signal is preset to SIGHUP but can be customized via " +"`sig_reload` if necessary." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:515 +msgid "" +"➑⓮ Our script supports two non-standard commands, `plugh` and " +"`xyzzy`. We saw them listed in `extra_commands`, and now it is time to " +"provide methods for them. The method for `xyzzy` is just inlined while that " +"for `plugh` is implemented as the `mumbled_plugh` function." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:519 +msgid "" +"Non-standard commands are not invoked during startup or shutdown. Usually " +"they are for the system admin's convenience. They can also be used from " +"other subsystems, e.g., man:devd[8] if specified in man:devd.conf[5]." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:522 +msgid "" +"The full list of available commands can be found in the usage line printed " +"by man:rc.subr[8] when the script is invoked without arguments. For " +"example, here is the usage line from the script under study:" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:527 +#, no-wrap +msgid "" +"# /etc/rc.d/mumbled\n" +"Usage: /etc/rc.d/mumbled [fast|force|one](start|stop|restart|rcvar|reload|plugh|xyzzy|status|poll)\n" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:534 +msgid "" +"⓭ A script can invoke its own standard or non-standard commands if " +"needed. This may look similar to calling functions, but we know that " +"commands and shell functions are not always the same thing. For instance, " +"`xyzzy` is not implemented as a function here. In addition, there can be a " +"pre-command and post-command, which should be invoked orderly. So the " +"proper way for a script to run its own command is by means of man:rc." +"subr[8], as shown in the example." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:540 +msgid "" +"➒ A handy function named `checkyesno` is provided by man:rc.subr[8]. " +"It takes a variable name as its argument and returns a zero exit code if and " +"only if the variable is set to `YES`, or `TRUE`, or `ON`, or `1`, case " +"insensitive; a non-zero exit code is returned otherwise. In the latter " +"case, the function tests the variable for being set to `NO`, `FALSE`, `OFF`, " +"or `0`, case insensitive; it prints a warning message if the variable " +"contains anything else, i.e., junk." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:542 +msgid "" +"Keep in mind that for man:sh[1] a zero exit code means true and a non-zero " +"exit code means false." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:547 +msgid "" +"The `checkyesno` function takes a __variable name__. Do not pass the " +"expanded _value_ of a variable to it; it will not work as expected." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:549 +msgid "The following is the correct usage of `checkyesno`:" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:555 +#, no-wrap +msgid "" +"if checkyesno mumbled_enable; then\n" +" foo\n" +"fi\n" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:558 +msgid "" +"On the contrary, calling `checkyesno` as shown below will not work - at " +"least not as expected:" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:564 +#, no-wrap +msgid "" +"if checkyesno \"${mumbled_enable}\"; then\n" +" foo\n" +"fi\n" +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:569 +msgid "" +"➓ [[rc-flags]]We can affect the flags to be passed to `$command` by " +"modifying `rc_flags` in `$start_precmd`." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:573 +msgid "" +"⓫ In certain cases we may need to emit an important message that " +"should go to `syslog` as well. This can be done easily with the following " +"man:rc.subr[8] functions: `debug`, `info`, `warn`, and `err`. The latter " +"function then exits the script with the code specified." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:577 +msgid "" +"⓬ The exit codes from methods and their pre-commands are not just " +"ignored by default. If `argument_precmd` returns a non-zero exit code, the " +"main method will not be performed. In turn, `argument_postcmd` will not be " +"invoked unless the main method returns a zero exit code." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:581 +msgid "" +"However, man:rc.subr[8] can be instructed from the command line to ignore " +"those exit codes and invoke all commands anyway by prefixing an argument " +"with `force`, as in `forcestart`." +msgstr "" + +#. type: Title == +#: documentation/content/en/articles/rc-scripting/_index.adoc:584 +#, no-wrap +msgid "Connecting a script to the rc.d framework" +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:591 +msgid "" +"After a script has been written, it needs to be integrated into [." +"filename]#rc.d#. The crucial step is to install the script in [.filename]#/" +"etc/rc.d# (for the base system) or [.filename]#/usr/local/etc/rc.d# (for " +"ports). Both [.filename]#bsd.prog.mk# and [.filename]#bsd.port.mk# provide " +"convenient hooks for that, and usually you do not have to worry about the " +"proper ownership and mode. System scripts should be installed from [." +"filename]#src/libexec/rc/rc.d# through the [.filename]#Makefile# found " +"there. Port scripts can be installed using `USE_RC_SUBR` as described " +"extref:{porters-handbook}[in the Porter's Handbook, rc-scripts]." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:596 +msgid "" +"However, we should consider beforehand the place of our script in the system " +"startup sequence. The service handled by our script is likely to depend on " +"other services. For instance, a network daemon cannot function without the " +"network interfaces and routing up and running. Even if a service seems to " +"demand nothing, it can hardly start before the basic filesystems have been " +"checked and mounted." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:602 +msgid "" +"We mentioned man:rcorder[8] already. Now it is time to have a close look at " +"it. In a nutshell, man:rcorder[8] takes a set of files, examines their " +"contents, and prints a dependency-ordered list of files from the set to " +"`stdout`. The point is to keep dependency information _inside_ the files so " +"that each file can speak for itself only. A file can specify the following " +"information:" +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:604 +msgid "" +"the names of the \"conditions\" (which means services to us) it __provides__;" +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:605 +msgid "the names of the \"conditions\" it __requires__;" +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:606 +msgid "the names of the \"conditions\" this file should run __before__;" +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:607 +msgid "" +"additional _keywords_ that can be used to select a subset from the whole set " +"of files (man:rcorder[8] can be instructed via options to include or omit " +"the files having particular keywords listed.)" +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:612 +msgid "" +"It is no surprise that man:rcorder[8] can handle only text files with a " +"syntax close to that of man:sh[1]. That is, special lines understood by man:" +"rcorder[8] look like man:sh[1] comments. The syntax of such special lines " +"is rather rigid to simplify their processing. See man:rcorder[8] for " +"details." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:615 +msgid "" +"Besides using man:rcorder[8] special lines, a script can insist on its " +"dependency upon another service by just starting it forcibly. This can be " +"needed when the other service is optional and will not start by itself " +"because the system admin has disabled it mistakenly in man:rc.conf[5]." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:617 +msgid "" +"With this general knowledge in mind, let us consider the simple daemon " +"script enhanced with dependency stuff:" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:626 +#, no-wrap +msgid "" +"# PROVIDE: mumbled oldmumble <.>\n" +"# REQUIRE: DAEMON cleanvar frotz <.>\n" +"# BEFORE: LOGIN <.>\n" +"# KEYWORD: nojail shutdown <.>\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:634 +#, no-wrap +msgid "" +"command=\"/usr/sbin/${name}\"\n" +"start_precmd=\"${name}_prestart\"\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:643 +#, no-wrap +msgid "" +"mumbled_prestart()\n" +"{\n" +"\tif ! checkyesno frotz_enable && \\\n" +"\t ! /etc/rc.d/frotz forcestatus 1>/dev/null 2>&1; then\n" +"\t\tforce_depend frotz || return 1 <.>\n" +"\tfi\n" +"\treturn 0\n" +"}\n" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:649 +msgid "As before, detailed analysis follows:" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:652 +msgid "" +"➊ That line declares the names of \"conditions\" our script " +"provides. Now other scripts can record a dependency on our script by those " +"names." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:657 +msgid "" +"Usually a script specifies a single condition provided. However, nothing " +"prevents us from listing several conditions there, e.g., for compatibility " +"reasons." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:659 +msgid "" +"In any case, the name of the main, or the only, `PROVIDE:` condition should " +"be the same as `${name}`." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:663 +msgid "" +"➋➌ So our script indicates which \"conditions\" provided by " +"other scripts it depends on. According to the lines, our script asks man:" +"rcorder[8] to put it after the script(s) providing [.filename]#DAEMON# and [." +"filename]#cleanvar#, but before that providing [.filename]#LOGIN#." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:669 +msgid "" +"The `BEFORE:` line should not be abused to work around an incomplete " +"dependency list in the other script. The appropriate case for using `BEFORE:" +"` is when the other script does not care about ours, but our script can do " +"its task better if run before the other one. A typical real-life example is " +"the network interfaces vs. the firewall: While the interfaces do not depend " +"on the firewall in doing their job, the system security will benefit from " +"the firewall being ready before there is any network traffic." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:673 +msgid "" +"Besides conditions corresponding to a single service each, there are meta-" +"conditions and their \"placeholder\" scripts used to ensure that certain " +"groups of operations are performed before others. These are denoted by [." +"filename]#UPPERCASE# names. Their list and purposes can be found in man:" +"rc[8]." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:679 +msgid "" +"Keep in mind that putting a service name in the `REQUIRE:` line does not " +"guarantee that the service will actually be running by the time our script " +"starts. The required service may fail to start or just be disabled in man:" +"rc.conf[5]. Obviously, man:rcorder[8] cannot track such details, and man:" +"rc[8] will not do that either. Consequently, the application started by our " +"script should be able to cope with any required services being unavailable. " +"In certain cases, we can help it as discussed <<forcedep, below>>" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:684 +msgid "" +"[[keywords]]➍ As we remember from the above text, man:rcorder[8] " +"keywords can be used to select or leave out some scripts. Namely any man:" +"rcorder[8] consumer can specify through `-k` and `-s` options which keywords " +"are on the \"keep list\" and \"skip list\", respectively. From all the " +"files to be dependency sorted, man:rcorder[8] will pick only those having a " +"keyword from the keep list (unless empty) and not having a keyword from the " +"skip list." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:687 +msgid "" +"In FreeBSD, man:rcorder[8] is used by [.filename]#/etc/rc# and [.filename]#/" +"etc/rc.shutdown#. These two scripts define the standard list of FreeBSD [." +"filename]#rc.d# keywords and their meanings as follows:" +msgstr "" + +#. type: Labeled list +#: documentation/content/en/articles/rc-scripting/_index.adoc:688 +#, no-wrap +msgid "nojail" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:690 +msgid "" +"The service is not for man:jail[8] environment. The automatic startup and " +"shutdown procedures will ignore the script if inside a jail." +msgstr "" + +#. type: Labeled list +#: documentation/content/en/articles/rc-scripting/_index.adoc:691 +#, no-wrap +msgid "nostart" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:694 +msgid "" +"The service is to be started manually or not started at all. The automatic " +"startup procedure will ignore the script. In conjunction with the [." +"filename]#shutdown# keyword, this can be used to write scripts that do " +"something only at system shutdown." +msgstr "" + +#. type: Labeled list +#: documentation/content/en/articles/rc-scripting/_index.adoc:695 +#, no-wrap +msgid "shutdown" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:696 +msgid "" +"This keyword is to be listed __explicitly__ if the service needs to be " +"stopped before system shutdown." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:709 +msgid "" +"When the system is going to shut down, [.filename]#/etc/rc.shutdown# runs. " +"It assumes that most [.filename]#rc.d# scripts have nothing to do at that " +"time. Therefore [.filename]#/etc/rc.shutdown# selectively invokes [." +"filename]#rc.d# scripts with the [.filename]#shutdown# keyword, effectively " +"ignoring the rest of the scripts. For even faster shutdown, [.filename]#/" +"etc/rc.shutdown# passes the [.filename]#faststop# 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# runs the scripts in reverse dependency order. " +"If writing a real [.filename]#rc.d# script, you should consider whether it " +"is relevant at system shutdown time. E.g., if your script does its work in " +"response to the [.filename]#start# command only, then you need not to " +"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 man:halt[8]. 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." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:713 +msgid "" +"[[forcedep]]➎ To begin with, `force_depend` should be used with much " +"care. It is generally better to revise the hierarchy of configuration " +"variables for your [.filename]#rc.d# scripts if they are interdependent." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:722 +msgid "" +"If you still cannot do without `force_depend`, the example offers an idiom " +"of how to invoke it conditionally. In the example, our `mumbled` daemon " +"requires that another one, `frotz`, be started in advance. However, `frotz` " +"is optional, too; and man:rcorder[8] knows nothing about such details. " +"Fortunately, our script has access to all man:rc.conf[5] variables. If " +"`frotz_enable` is true, we hope for the best and rely on [.filename]#rc.d# " +"to have started `frotz`. Otherwise we forcibly check the status of " +"`frotz`. Finally, we enforce our dependency on `frotz` if it is found to be " +"not running. A warning message will be emitted by `force_depend` because it " +"should be invoked only if a misconfiguration has been detected." +msgstr "" + +#. type: Title == +#: documentation/content/en/articles/rc-scripting/_index.adoc:724 +#, no-wrap +msgid "Giving more flexibility to an rc.d script" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:733 +msgid "" +"When invoked during startup or shutdown, an [.filename]#rc.d# script is " +"supposed to act on the entire subsystem it is responsible for. E.g., [." +"filename]#/etc/rc.d/netif# 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 `start` or `stop`. Between startup and " +"shutdown, [.filename]#rc.d# 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# script calls for an extra argument, the " +"interface name." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:736 +msgid "" +"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." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:741 +msgid "" +"How can man:rc.subr[8] 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# dictates that it is for the main script to decide which " +"arguments are to be passed to its methods." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:745 +msgid "" +"So the approach adopted by man:rc.subr[8] is as follows: `run_rc_command` " +"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: " +"`start`, `stop`, etc. It will be shifted out by `run_rc_command`, so what " +"is `$2` in the original command line will be presented as `$1` to the " +"method, and so on." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:748 +msgid "" +"To illustrate this opportunity, let us modify the primitive dummy script so " +"that its messages depend on the additional arguments supplied. Here we go:" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:760 +#, no-wrap +msgid "" +"name=\"dummy\"\n" +"start_cmd=\"${name}_start\"\n" +"stop_cmd=\":\"\n" +"kiss_cmd=\"${name}_kiss\"\n" +"extra_commands=\"kiss\"\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:769 +#, no-wrap +msgid "" +"dummy_start()\n" +"{\n" +" if [ $# -gt 0 ]; then <.>\n" +" echo \"Greeting message: $*\"\n" +" else\n" +" echo \"Nothing started.\"\n" +" fi\n" +"}\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:785 +#, no-wrap +msgid "" +"dummy_kiss()\n" +"{\n" +" echo -n \"A ghost gives you a kiss\"\n" +" if [ $# -gt 0 ]; then <.>\n" +" echo -n \" and whispers: $*\"\n" +" fi\n" +" case \"$*\" in\n" +" *[.!?])\n" +" echo\n" +" ;;\n" +" *)\n" +" echo .\n" +" ;;\n" +" esac\n" +"}\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:788 +#, no-wrap +msgid "" +"load_rc_config $name\n" +"run_rc_command \"$@\" <.>\n" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:791 +msgid "What essential changes can we notice in the script?" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:796 +msgid "" +"➊ All arguments you type after `start` 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 `$*` within the " +"double quotes. Here is how the script can be invoked now:" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:801 +#, no-wrap +msgid "" +"# /etc/rc.d/dummy start\n" +"Nothing started.\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:804 +#, no-wrap +msgid "" +"# /etc/rc.d/dummy start Hello world!\n" +"Greeting message: Hello world!\n" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:808 +msgid "" +"➋ The same applies to any method our script provides, not only to a " +"standard one. We have added a custom method named `kiss`, and it can take " +"advantage of the extra arguments not less than `start` does. E.g.:" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:813 +#, no-wrap +msgid "" +"# /etc/rc.d/dummy kiss\n" +"A ghost gives you a kiss.\n" +msgstr "" + +#. type: delimited block . 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:816 +#, no-wrap +msgid "" +"# /etc/rc.d/dummy kiss Once I was Etaoin Shrdlu...\n" +"A ghost gives you a kiss and whispers: Once I was Etaoin Shrdlu...\n" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:819 +msgid "" +"➌ If we want just to pass all extra arguments to any method, we can " +"merely substitute `\"$@\"` for `\"$1\"` in the last line of our script, " +"where we invoke `run_rc_command`." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:825 +msgid "" +"An man:sh[1] programmer ought to understand the subtle difference between " +"`$*` and `$@` as the ways to designate all positional parameters. For its " +"in-depth discussion, refer to a good handbook on man:sh[1] scripting. _Do " +"not_ use the expressions until you fully understand them because their " +"misuse will result in buggy and insecure scripts." +msgstr "" + +#. type: delimited block = 4 +#: documentation/content/en/articles/rc-scripting/_index.adoc:832 +msgid "" +"Currently `run_rc_command` 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 `$*` misuse." +msgstr "" + +#. type: Title == +#: documentation/content/en/articles/rc-scripting/_index.adoc:835 +#, no-wrap +msgid "Further reading" +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:839 +msgid "" +"[[lukem]]http://www.mewburn.net/luke/papers/rc.d.pdf[The original article by " +"Luke Mewburn] offers a general overview of [.filename]#rc.d# and detailed " +"rationale for its design decisions. It provides insight on the whole [." +"filename]#rc.d# framework and its place in a modern BSD operating system." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:842 +msgid "" +"[[manpages]]The manual pages man:rc[8], man:rc.subr[8], and man:rcorder[8] " +"document the [.filename]#rc.d# components in great detail. You cannot fully " +"use the [.filename]#rc.d# power without studying the manual pages and " +"referring to them while writing your own scripts." +msgstr "" + +#. type: Plain text +#: documentation/content/en/articles/rc-scripting/_index.adoc:846 +msgid "" +"The major source of working, real-life examples is [.filename]#/etc/rc.d# in " +"a live system. Its contents are easy and pleasant to read because most " +"rough corners are hidden deep in man:rc.subr[8]. Keep in mind though that " +"the [.filename]#/etc/rc.d# scripts were not written by angels, so they might " +"suffer from bugs and suboptimal design decisions. Now you can improve them!" +msgstr "" |