[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#562506: init scripts should not use set -e



Russ Allbery <rra@debian.org> writes:

> Currently, Debian Policy makes a general statement that all Bourne shell
> scripts should start with set -e and does not (so far as I can see) make
> an exception for init scripts.  I've seen several init scripts use set
> -e, which is usually a bad idea.  It assumes that the shell function
> libraries used for status reporting are "set -e"-clean, which they may
> not be, and it causes the init scripts to exit in non-obvious ways and
> produce lots of debugging headache.

> I think there's already a consensus that set -e is the wrong approach
> for init scripts and instead the exit status of key commands should be
> checked instead.  I think Policy should reflect that consensus somewhere
> in the section on init scripts.

Here is proposed wording, which hopefully reflects the subsequent
discussion.  I'm looking for seconds.

diff --git a/policy.sgml b/policy.sgml
index d16df70..1871d4c 100644
--- a/policy.sgml
+++ b/policy.sgml
@@ -6011,7 +6011,7 @@ rmdir /usr/local/share/emacs 2>/dev/null || true
 	  </p>
 	</sect1>
 
-	<sect1>
+	<sect1 id="writing-init">
 	  <heading>Writing the scripts</heading>
 
 	  <p>
@@ -6062,6 +6062,23 @@ rmdir /usr/local/share/emacs 2>/dev/null || true
 	  </p>
 
 	  <p>
+	    Be careful of using <tt>set -e</tt> in <file>init.d</file>
+	    scripts.  Writing correct <file>init.d</file> scripts requires
+	    accepting various error exit statuses when daemons are already
+	    running or already stopped without aborting
+	    the <file>init.d</file> script, and common <file>init.d</file>
+	    function libraries are not safe to call with <tt>set -e</tt>
+	    in effect<footnote>
+	      <tt>/lib/lsb/init-functions</tt>, which assists in writing
+	      LSB-compliant init scripts, may fail if <tt>set -e</tt> is
+	      in effect and echoing status messages to the console fails,
+	      for example.
+	    </footnote>.  For <tt>init.d</tt> scripts, it's often easier
+	    to not use <tt>set -e</tt> and instead check the result of
+	    each command separately.
+	  </p>
+
+	  <p>
 	    If a service reloads its configuration automatically (as
 	    in the case of <prgn>cron</prgn>, for example), the
 	    <tt>reload</tt> option of the <file>init.d</file> script
@@ -7158,13 +7175,19 @@ strip --strip-unneeded <var>your-lib</var>
           language currently used to implement it.
         </p>
 	<p>
-	  Shell scripts (<prgn>sh</prgn> and <prgn>bash</prgn>)
-	  should almost certainly start with <tt>set -e</tt> so that
-	  errors are detected.  Every script should use
-	  <tt>set -e</tt> or check the exit status of <em>every</em>
-	  command.
+	  Shell scripts (<prgn>sh</prgn> and <prgn>bash</prgn>) other than
+	  <file>init.d</file> scripts should almost certainly start
+	  with <tt>set -e</tt> so that errors are detected.
+	  <file>init.d</file> scripts are something of a special case, due
+	  to how frequently they need to call commands that are allowed to
+	  fail, and it may instead be easier to check the exit status of
+	  commands directly.  See <ref id="writing-init"> for more
+	  information about writing <file>init.d</file> scripts.
+	</p>
+	<p>
+	  Every script should use <tt>set -e</tt> or check the exit status
+	  of <em>every</em> command.
 	</p>
-
 	<p>
 	  Scripts may assume that <file>/bin/sh</file> implements the
 	  SUSv3 Shell Command Language<footnote>

-- 
Russ Allbery (rra@debian.org)               <http://www.eyrie.org/~eagle/>



Reply to: