HEX
Server: Apache
System: Linux pdx1-shared-a1-38 6.6.104-grsec-jammy+ #3 SMP Tue Sep 16 00:28:11 UTC 2025 x86_64
User: mmickelson (3396398)
PHP: 8.1.31
Disabled: NONE
Upload Files
File: //usr/share/doc/debian-policy/policy.html/ch-maintainerscripts.html
<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />

    <title>6. Package maintainer scripts and installation procedure &#8212; Debian Policy Manual v4.6.0.1</title>
    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
    <link rel="stylesheet" type="text/css" href="_static/nature.css" />
    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
    <script src="_static/jquery.js"></script>
    <script src="_static/underscore.js"></script>
    <script src="_static/doctools.js"></script>
    <link rel="index" title="Index" href="genindex.html" />
    <link rel="search" title="Search" href="search.html" />
    <link rel="next" title="7. Declaring relationships between packages" href="ch-relationships.html" />
    <link rel="prev" title="5. Control files and their fields" href="ch-controlfields.html" /> 
  </head><body>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="ch-relationships.html" title="7. Declaring relationships between packages"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="ch-controlfields.html" title="5. Control files and their fields"
             accesskey="P">previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="index.html">Debian Policy Manual v4.6.0.1</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href=""><span class="section-number">6. </span>Package maintainer scripts and installation procedure</a></li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <section id="package-maintainer-scripts-and-installation-procedure">
<h1><span class="section-number">6. </span>Package maintainer scripts and installation procedure<a class="headerlink" href="#package-maintainer-scripts-and-installation-procedure" title="Permalink to this headline">¶</a></h1>
<section id="introduction-to-package-maintainer-scripts">
<span id="s6-1"></span><h2><span class="section-number">6.1. </span>Introduction to package maintainer scripts<a class="headerlink" href="#introduction-to-package-maintainer-scripts" title="Permalink to this headline">¶</a></h2>
<p>It is possible to supply scripts as part of a package which the package
management system will run for you when your package is installed,
upgraded or removed.</p>
<p>These scripts are the control information files <code class="docutils literal notranslate"><span class="pre">preinst</span></code>,
<code class="docutils literal notranslate"><span class="pre">postinst</span></code>, <code class="docutils literal notranslate"><span class="pre">prerm</span></code> and <code class="docutils literal notranslate"><span class="pre">postrm</span></code>. They must be proper executable
files; if they are scripts (which is recommended), they must start with
the usual <code class="docutils literal notranslate"><span class="pre">#!</span></code> convention. They should be readable and executable by
anyone, and must not be world-writable.</p>
<p>The package management system looks at the exit status from these
scripts. It is important that they exit with a non-zero status if there
is an error, so that the package management system can stop its
processing. For shell scripts this means that you <em>almost always</em> need
to use <code class="docutils literal notranslate"><span class="pre">set</span> <span class="pre">-e</span></code> (this is usually true when writing shell scripts, in fact).
It is also important, of course, that they exit with a zero status if
everything went well.</p>
<p>Additionally, packages interacting with users using <code class="docutils literal notranslate"><span class="pre">debconf</span></code> in the
<code class="docutils literal notranslate"><span class="pre">postinst</span></code> script should install a <code class="docutils literal notranslate"><span class="pre">config</span></code> script as a control
information file. See <a class="reference internal" href="ch-binary.html#s-maintscriptprompt"><span class="std std-ref">Prompting in maintainer scripts</span></a> for
details.</p>
<p>When a package is upgraded a combination of the scripts from the old and
new packages is called during the upgrade procedure. If your scripts are
going to be at all complicated you need to be aware of this, and may
need to check the arguments to your scripts.</p>
<p>Broadly speaking the <code class="docutils literal notranslate"><span class="pre">preinst</span></code> is called before (a particular version
of) a package is unpacked, and the <code class="docutils literal notranslate"><span class="pre">postinst</span></code> afterwards; the
<code class="docutils literal notranslate"><span class="pre">prerm</span></code> before (a version of) a package is removed and the <code class="docutils literal notranslate"><span class="pre">postrm</span></code>
afterwards.</p>
<p>Programs called from maintainer scripts should not normally have a path
prepended to them. Before installation is started, the package
management system checks to see if the programs <code class="docutils literal notranslate"><span class="pre">ldconfig</span></code>,
<code class="docutils literal notranslate"><span class="pre">start-stop-daemon</span></code>, and <code class="docutils literal notranslate"><span class="pre">update-rc.d</span></code> can be found via the <code class="docutils literal notranslate"><span class="pre">PATH</span></code>
environment variable. Those programs, and any other program that one
would expect to be in the <code class="docutils literal notranslate"><span class="pre">PATH</span></code>, should thus be invoked without an
absolute pathname. Maintainer scripts should also not reset the
<code class="docutils literal notranslate"><span class="pre">PATH</span></code>, though they might choose to modify it by prepending or
appending package-specific directories. These considerations really
apply to all shell scripts.</p>
</section>
<section id="maintainer-scripts-idempotency">
<span id="s-idempotency"></span><h2><span class="section-number">6.2. </span>Maintainer scripts idempotency<a class="headerlink" href="#maintainer-scripts-idempotency" title="Permalink to this headline">¶</a></h2>
<p>It is necessary for the error recovery procedures that the scripts be
idempotent. This means that if it is run successfully, and then it is
called again, it doesn’t bomb out or cause any harm, but just ensures
that everything is the way it ought to be. If the first call failed, or
aborted half way through for some reason, the second call should merely
do the things that were left undone the first time, if any, and exit
with a success status if everything is OK.  <a class="footnote-reference brackets" href="#id8" id="id1">1</a></p>
</section>
<section id="controlling-terminal-for-maintainer-scripts">
<span id="s-controllingterminal"></span><h2><span class="section-number">6.3. </span>Controlling terminal for maintainer scripts<a class="headerlink" href="#controlling-terminal-for-maintainer-scripts" title="Permalink to this headline">¶</a></h2>
<p>Maintainer scripts are not guaranteed to run with a controlling terminal
and may not be able to interact with the user. They must be able to fall
back to noninteractive behavior if no controlling terminal is available.
Maintainer scripts that prompt via a program conforming to the Debian
Configuration Management Specification (see
<a class="reference internal" href="ch-binary.html#s-maintscriptprompt"><span class="std std-ref">Prompting in maintainer scripts</span></a>) may assume that program will
handle falling back to noninteractive behavior.</p>
<p>For high-priority prompts without a reasonable default answer,
maintainer scripts may abort if there is no controlling terminal.
However, this situation should be avoided if at all possible, since it
prevents automated or unattended installs. In most cases, users will
consider this to be a bug in the package.</p>
</section>
<section id="exit-status">
<span id="s-exitstatus"></span><h2><span class="section-number">6.4. </span>Exit status<a class="headerlink" href="#exit-status" title="Permalink to this headline">¶</a></h2>
<p>Each script must return a zero exit status for success, or a nonzero one
for failure, since the package management system looks for the exit
status of these scripts and determines what action to take next based on
that datum.</p>
</section>
<section id="summary-of-ways-maintainer-scripts-are-called">
<span id="s-mscriptsinstact"></span><h2><span class="section-number">6.5. </span>Summary of ways maintainer scripts are called<a class="headerlink" href="#summary-of-ways-maintainer-scripts-are-called" title="Permalink to this headline">¶</a></h2>
<p>What follows is a summary of all the ways in which maintainer scripts
may be called along with what facilities those scripts may rely on being
available at that time. Script names preceded by new- are the scripts
from the new version of a package being installed, upgraded to, or
downgraded to. Script names preceded by old- are the scripts from the
old version of a package that is being upgraded from or downgraded from.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">preinst</span></code> script may be called in the following ways:</p>
<div class="line-block">
<div class="line"><code class="docutils literal notranslate"><span class="pre">new-preinst</span></code> install</div>
<div class="line"><code class="docutils literal notranslate"><span class="pre">new-preinst</span></code> install <em>old-version</em></div>
<div class="line"><code class="docutils literal notranslate"><span class="pre">new-preinst</span></code> upgrade <em>old-version</em></div>
</div>
<blockquote>
<div><p>The package will not yet be unpacked, so the <code class="docutils literal notranslate"><span class="pre">preinst</span></code> script
cannot rely on any files included in its package. Only essential
packages and pre-dependencies (<code class="docutils literal notranslate"><span class="pre">Pre-Depends</span></code>) may be assumed to be
available. Pre-dependencies will have been configured at least once,
but at the time the <code class="docutils literal notranslate"><span class="pre">preinst</span></code> is called they may only be in an
“Unpacked” or “Half-Configured” state if a previous version of the
pre-dependency was completely configured and has not been removed
since then.</p>
</div></blockquote>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">old-preinst</span></code> abort-upgrade <em>new-version</em></dt><dd><p>Called during error handling of an upgrade that failed after
unpacking the new package because the <code class="docutils literal notranslate"><span class="pre">postrm</span> <span class="pre">upgrade</span></code> action failed. The unpacked files may be
partly from the new version or partly missing, so the script cannot
rely on files included in the package. Package dependencies may not
be available. Pre-dependencies will be at least “Unpacked” following
the same rules as above, except they may be only “Half-Installed” if
an upgrade of the pre-dependency failed.  <a class="footnote-reference brackets" href="#id9" id="id2">2</a></p>
</dd>
</dl>
<p>The <code class="docutils literal notranslate"><span class="pre">postinst</span></code> script may be called in the following ways:</p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">postinst</span></code> configure <em>most-recently-configured-version</em></dt><dd><p>The files contained in the package will be unpacked. All package
dependencies will at least be “Unpacked”. If there are no circular
dependencies involved, all package dependencies will be configured.
For behavior in the case of circular dependencies, see the
discussion in <a class="reference internal" href="ch-relationships.html#s-binarydeps"><span class="std std-ref">Binary Dependencies - Depends, Recommends, Suggests, Enhances, Pre-Depends</span></a>.</p>
</dd>
</dl>
<div class="line-block">
<div class="line"><code class="docutils literal notranslate"><span class="pre">old-postinst</span></code> abort-upgrade <em>new-version</em></div>
<div class="line"><code class="docutils literal notranslate"><span class="pre">conflictor's-postinst</span></code> abort-remove in-favour <em>package</em> <em>new-version</em></div>
<div class="line"><code class="docutils literal notranslate"><span class="pre">postinst</span></code> abort-remove</div>
<div class="line"><code class="docutils literal notranslate"><span class="pre">deconfigured's-postinst</span></code> abort-deconfigure in-favour <em>failed-install-package</em> <em>version</em> [ removing conflicting-package version ]</div>
</div>
<blockquote>
<div><p>The files contained in the package will be unpacked. All package
dependencies will at least be “Half-Installed” and will have
previously been configured and not removed. However, dependencies
may not be configured or even fully unpacked in some error
situations.  <a class="footnote-reference brackets" href="#id10" id="id3">3</a> The <code class="docutils literal notranslate"><span class="pre">postinst</span></code> should still attempt any actions
for which its dependencies are required, since they will normally be
available, but consider the correct error handling approach if those
actions fail. Aborting the <code class="docutils literal notranslate"><span class="pre">postinst</span></code> action if commands or
facilities from the package dependencies are not available is often
the best approach.</p>
</div></blockquote>
<p>The <code class="docutils literal notranslate"><span class="pre">prerm</span></code> script may be called in the following ways:</p>
<div class="line-block">
<div class="line"><code class="docutils literal notranslate"><span class="pre">prerm</span></code> remove</div>
<div class="line"><code class="docutils literal notranslate"><span class="pre">old-prerm</span></code> upgrade <em>new-version</em></div>
<div class="line"><code class="docutils literal notranslate"><span class="pre">conflictor's-prerm</span></code> remove in-favour package <em>new-version</em></div>
<div class="line"><code class="docutils literal notranslate"><span class="pre">deconfigured's-prerm</span></code> deconfigure in-favour <em>package-being-installed</em> <em>version</em> [removing conflicting-package version]</div>
</div>
<blockquote>
<div><p>The package whose <code class="docutils literal notranslate"><span class="pre">prerm</span></code> is being called will be at least
“Half-Installed”. All package dependencies will at least be
“Half-Installed” and will have previously been configured and not
removed. If there was no error, all dependencies will at least be
“Unpacked”, but these actions may be called in various error states
where dependencies are only “Half-Installed” due to a partial
upgrade.</p>
</div></blockquote>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">new-prerm</span></code> failed-upgrade <em>old-version</em></dt><dd><p>Called during error handling when <code class="docutils literal notranslate"><span class="pre">prerm</span> <span class="pre">upgrade</span></code> fails. The new package will not yet be
unpacked, and all the same constraints as for <code class="docutils literal notranslate"><span class="pre">preinst</span> <span class="pre">upgrade</span></code>
apply.</p>
</dd>
</dl>
<p>The <code class="docutils literal notranslate"><span class="pre">postrm</span></code> script may be called in the following ways:</p>
<div class="line-block">
<div class="line"><code class="docutils literal notranslate"><span class="pre">postrm</span></code> remove</div>
<div class="line"><code class="docutils literal notranslate"><span class="pre">postrm</span></code> purge</div>
<div class="line"><code class="docutils literal notranslate"><span class="pre">old-postrm</span></code> upgrade <em>new-version</em></div>
<div class="line"><code class="docutils literal notranslate"><span class="pre">disappearer's-postrm</span></code> disappear overwriter <em>overwriter-version</em></div>
</div>
<blockquote>
<div><p>The <code class="docutils literal notranslate"><span class="pre">postrm</span></code> script is called after the package’s files have been
removed or replaced. The package whose <code class="docutils literal notranslate"><span class="pre">postrm</span></code> is being called
may have previously been deconfigured and only be “Unpacked”, at
which point subsequent package changes do not consider its
dependencies. Therefore, all <code class="docutils literal notranslate"><span class="pre">postrm</span></code> actions must only rely on
essential packages and must gracefully skip any actions that require
the package’s dependencies if those dependencies are unavailable.
<a class="footnote-reference brackets" href="#id11" id="id4">4</a></p>
</div></blockquote>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">new-postrm</span></code> failed-upgrade <em>old-version</em></dt><dd><p>Called when the old <code class="docutils literal notranslate"><span class="pre">postrm</span> <span class="pre">upgrade</span></code> action fails. The new package
will be unpacked, but only essential packages and pre-dependencies
can be relied on. Pre-dependencies will either be configured or will
be “Unpacked” or “Half-Configured” but previously had been
configured and was never removed.</p>
</dd>
</dl>
<div class="line-block">
<div class="line"><code class="docutils literal notranslate"><span class="pre">new-postrm</span></code> abort-install</div>
<div class="line"><code class="docutils literal notranslate"><span class="pre">new-postrm</span></code> abort-install <em>old-version</em></div>
<div class="line"><code class="docutils literal notranslate"><span class="pre">new-postrm</span></code> abort-upgrade <em>old-version</em></div>
</div>
<blockquote>
<div><p>Called before unpacking the new package as part of the error
handling of <code class="docutils literal notranslate"><span class="pre">preinst</span></code> failures. May assume the same state as
<code class="docutils literal notranslate"><span class="pre">preinst</span></code> can assume.</p>
</div></blockquote>
</section>
<section id="details-of-unpack-phase-of-installation-or-upgrade">
<span id="s-unpackphase"></span><h2><span class="section-number">6.6. </span>Details of unpack phase of installation or upgrade<a class="headerlink" href="#details-of-unpack-phase-of-installation-or-upgrade" title="Permalink to this headline">¶</a></h2>
<p>The procedure on installation/upgrade/overwrite/disappear (i.e., when
running <code class="docutils literal notranslate"><span class="pre">dpkg</span> <span class="pre">--unpack</span></code>, or the unpack stage of <code class="docutils literal notranslate"><span class="pre">dpkg</span> <span class="pre">--install</span></code>) is
as follows.  <a class="footnote-reference brackets" href="#id12" id="id5">5</a> In each case, if a major error occurs (unless listed
below) the actions are, in general, run backwards - this means that the
maintainer scripts are run with different arguments in reverse order.
These are the “error unwind” calls listed below.</p>
<ol class="arabic">
<li><p>Notify the currently installed package:</p>
<ol class="loweralpha">
<li><p>If a version of the package is already “Installed”, call</p>
<pre class="literal-block">old-prerm upgrade <em>new-version</em></pre>
</li>
<li><p>If the script runs but exits with a non-zero exit status,
<code class="docutils literal notranslate"><span class="pre">dpkg</span></code> will attempt:</p>
<pre class="literal-block">new-prerm failed-upgrade <em>old-version</em></pre>
<p>If this works, the upgrade continues. If this does not work, the
error unwind:</p>
<pre class="literal-block"><em>old-postinst</em> abort-upgrade <em>new-version</em></pre>
<p>If this works, then the <em>old-version</em> is “Installed”, if not, the
old version is in a “Half-Configured” state.</p>
</li>
</ol>
</li>
<li><p>If a “conflicting” package is being removed at the same time, or if
any package will be broken (due to <code class="docutils literal notranslate"><span class="pre">Breaks</span></code>):</p>
<ol class="loweralpha">
<li><p>If <code class="docutils literal notranslate"><span class="pre">--auto-deconfigure</span></code> is specified, call, for each package to
be deconfigured due to <code class="docutils literal notranslate"><span class="pre">Breaks</span></code>:</p>
<pre class="literal-block"><em>deconfigured's-prerm</em> deconfigure \
    in-favour <em>package-being-installed</em> <em>version</em></pre>
<p>Error unwind:</p>
<pre class="literal-block"><em>deconfigured's-postinst</em> abort-deconfigure \
    in-favour <em>package-being-installed-but-failed</em> <em>version</em></pre>
<p>The deconfigured packages are marked as requiring configuration,
so that if <code class="docutils literal notranslate"><span class="pre">--install</span></code> is used they will be configured again if
possible.</p>
</li>
<li><p>If any packages depended on a conflicting package being removed
and <code class="docutils literal notranslate"><span class="pre">--auto-deconfigure</span></code> is specified, call, for each such
package:</p>
<pre class="literal-block"><em>deconfigured's-prerm</em> deconfigure \
   in-favour <em>package-being-installed</em> <em>version</em> \
   removing <em>conflicting-package</em> <em>version</em></pre>
<p>Error unwind:</p>
<pre class="literal-block"><em>deconfigured's-postinst</em> abort-deconfigure \
    in-favour <em>package-being-installed-but-failed</em> <em>version</em> \
    removing <em>conflicting-package</em> <em>version</em></pre>
<p>The deconfigured packages are marked as requiring configuration,
so that if <code class="docutils literal notranslate"><span class="pre">--install</span></code> is used they will be configured again if
possible.</p>
</li>
<li><p>To prepare for removal of each conflicting package, call:</p>
<pre class="literal-block"><em>conflictor's-prerm</em> remove \
    in-favour <em>package</em> <em>new-version</em></pre>
<p>Error unwind:</p>
<pre class="literal-block"><em>conflictor's-postinst</em> abort-remove \
    in-favour <em>package</em> <em>new-version</em></pre>
</li>
</ol>
</li>
<li><p>Run the <code class="docutils literal notranslate"><span class="pre">preinst</span></code> of the new package:</p>
<ol class="loweralpha">
<li><p>If the package is being upgraded, call:</p>
<pre class="literal-block"><em>new-preinst</em> upgrade <em>old-version</em></pre>
<p>If this fails, we call:</p>
<pre class="literal-block"><em>new-postrm</em> abort-upgrade <em>old-version</em></pre>
<ol class="lowerroman">
<li><p>If that works, then</p>
<pre class="literal-block"><em>old-postinst</em> abort-upgrade <em>new-version</em></pre>
<p>is called. If this works, then the old version is in an
“Installed” state, or else it is left in an “Unpacked” state.</p>
</li>
<li><p>If it fails, then the old version is left in an
“Half-Installed” state.</p></li>
</ol>
</li>
<li><p>Otherwise, if the package had some configuration files from a
previous version installed (i.e., it is in the “Config-Files”
state):</p>
<pre class="literal-block"><em>new-preinst</em> install <em>old-version</em></pre>
<p>Error unwind:</p>
<pre class="literal-block"><em>new-postrm</em> abort-install <em>old-version</em></pre>
<p>If this fails, the package is left in a “Half-Installed” state,
which requires a reinstall. If it works, the packages is left in
a “Config-Files” state.</p>
</li>
<li><p>Otherwise (i.e., the package was completely purged):</p>
<pre class="literal-block"><em>new-preinst</em> install</pre>
<p>Error unwind:</p>
<pre class="literal-block"><em>new-postrm</em> abort-install</pre>
<p>If the error-unwind fails, the package is in a “Half-Installed”
phase, and requires a reinstall. If the error unwind works, the
package is in the “Not-Installed” state.</p>
</li>
</ol>
</li>
<li><p>The new package’s files are unpacked, overwriting any that may be on
the system already, for example any from the old version of the same
package or from another package. Backups of the old files are kept
temporarily, and if anything goes wrong the package management
system will attempt to put them back as part of the error unwind.</p>
<p>It is an error for a package to contain files which are on the
system in another package, unless <code class="docutils literal notranslate"><span class="pre">Replaces</span></code> is used (see
<a class="reference internal" href="ch-relationships.html#s-replaces"><span class="std std-ref">Overwriting files and replacing packages - Replaces</span></a>).</p>
<p>It is a more serious error for a package to contain a plain file or
other kind of non-directory where another package has a directory
(again, unless <code class="docutils literal notranslate"><span class="pre">Replaces</span></code> is used). This error can be overridden
if desired using <code class="docutils literal notranslate"><span class="pre">--force-overwrite-dir</span></code>, but this is not
advisable.</p>
<p>Packages which overwrite each other’s files produce behavior which,
though deterministic, is hard for the system administrator to
understand. It can easily lead to “missing” programs if, for
example, a package is unpacked which overwrites a file from another
package, and is then removed again.  <a class="footnote-reference brackets" href="#id13" id="id6">6</a></p>
<p>A directory will never be replaced by a symbolic link to a directory
or vice versa; instead, the existing state (symlink or not) will be
left alone and <code class="docutils literal notranslate"><span class="pre">dpkg</span></code> will follow the symlink if there is one.</p>
</li>
<li><p>If the package is being upgraded:</p>
<ol class="loweralpha">
<li><p>Call:</p>
<pre class="literal-block"><em>old-postrm</em> upgrade <em>new-version</em></pre>
</li>
<li><p>If this fails, <code class="docutils literal notranslate"><span class="pre">dpkg</span></code> will attempt:</p>
<pre class="literal-block"><em>new-postrm</em> failed-upgrade <em>old-version</em></pre>
<p>If this works, installation continues. If not, Error unwind:</p>
<pre class="literal-block"><em>old-preinst</em> abort-upgrade <em>new-version</em></pre>
<p>If this fails, the old version is left in a “Half-Installed”
state. If it works, dpkg now calls:</p>
<pre class="literal-block"><em>new-postrm</em> abort-upgrade <em>old-version</em></pre>
<p>If this fails, the old version is left in a “Half-Installed”
state. If it works, dpkg now calls:</p>
<pre class="literal-block"><em>old-postinst</em> abort-upgrade <em>new-version</em></pre>
<p>If this fails, the old version is in an “Unpacked” state.</p>
</li>
</ol>
<p>This is the point of no return. If <code class="docutils literal notranslate"><span class="pre">dpkg</span></code> gets this far, it won’t
back off past this point if an error occurs. This will leave the
package in a fairly bad state, which will require a successful
re-installation to clear up, but it’s when <code class="docutils literal notranslate"><span class="pre">dpkg</span></code> starts doing
things that are irreversible.</p>
</li>
<li><p>Any files which were in the old version of the package but not in
the new are removed.</p></li>
<li><p>The new file list replaces the old.</p></li>
<li><p>The new maintainer scripts replace the old.</p></li>
<li><p>Any packages all of whose files have been overwritten during the
installation, and which aren’t required for dependencies, are
considered to have been removed. For each such package</p>
<ol class="loweralpha">
<li><p><code class="docutils literal notranslate"><span class="pre">dpkg</span></code> calls:</p>
<pre class="literal-block"><em>disappearer's-postrm</em> disappear \
    <em>overwriter</em> <em>overwriter-version</em></pre>
</li>
<li><p>The package’s maintainer scripts are removed.</p></li>
<li><p>It is noted in the status database as being in a sane state,
namely “Not-Installed” (any conffiles it may have are ignored,
rather than being removed by <code class="docutils literal notranslate"><span class="pre">dpkg</span></code>). Note that disappearing
packages do not have their prerm called, because <code class="docutils literal notranslate"><span class="pre">dpkg</span></code> doesn’t
know in advance that the package is going to vanish.</p></li>
</ol>
</li>
<li><p>Any files in the package we’re unpacking that are also listed in the
file lists of other packages are removed from those lists. (This
will lobotomize the file list of the “conflicting” package if there
is one.)</p></li>
<li><p>The backup files made during installation, above, are deleted.</p></li>
<li><p>The new package’s status is now sane, and recorded as “Unpacked”.</p>
<p>Here is another point of no return: if the conflicting package’s
removal fails we do not unwind the rest of the installation. The
conflicting package is left in a half-removed limbo.</p>
</li>
<li><p>If there was a conflicting package we go and do the removal actions
(described below), starting with the removal of the conflicting
package’s files (any that are also in the package being unpacked
have already been removed from the conflicting package’s file list,
and so do not get removed now).</p></li>
</ol>
</section>
<section id="details-of-configuration">
<span id="s-configdetails"></span><h2><span class="section-number">6.7. </span>Details of configuration<a class="headerlink" href="#details-of-configuration" title="Permalink to this headline">¶</a></h2>
<p>When we configure a package (this happens with <code class="docutils literal notranslate"><span class="pre">dpkg</span> <span class="pre">--install</span></code> and <code class="docutils literal notranslate"><span class="pre">dpkg</span> <span class="pre">--configure</span></code>), we first update any
<code class="docutils literal notranslate"><span class="pre">conffile</span></code>s and then call:</p>
<pre class="literal-block"><em>postinst</em> configure <em>most-recently-configured-version</em></pre>
<p>No attempt is made to unwind after errors during configuration. If the
configuration fails, the package is in a “Half-Configured” state, and an
error message is generated.</p>
<p>If there is no most recently configured version <code class="docutils literal notranslate"><span class="pre">dpkg</span></code> will pass a
null argument.  <a class="footnote-reference brackets" href="#id14" id="id7">7</a></p>
</section>
<section id="details-of-removal-and-or-configuration-purging">
<span id="s-removedetails"></span><h2><span class="section-number">6.8. </span>Details of removal and/or configuration purging<a class="headerlink" href="#details-of-removal-and-or-configuration-purging" title="Permalink to this headline">¶</a></h2>
<ol class="arabic">
<li><pre class="literal-block"><em>prerm</em> remove</pre>
<p>If prerm fails during replacement due to conflict</p>
<pre class="literal-block"><em>conflictor's-postinst</em> abort-remove \
    in-favour <em>package</em> <em>new-version</em></pre>
<p>Or else we call:</p>
<pre class="literal-block"><em>postinst</em> abort-remove</pre>
<p>If this fails, the package is in a “Half-Configured” state, or else
it remains “Installed”.</p>
</li>
<li><p>The package’s files are removed (except <code class="docutils literal notranslate"><span class="pre">conffile</span></code>s).</p></li>
<li><pre class="literal-block"><em>postrm</em> remove</pre>
<p>If it fails, there’s no error unwind, and the package is in an
“Half-Installed” state.</p>
</li>
<li><p>All the maintainer scripts except the <code class="docutils literal notranslate"><span class="pre">postrm</span></code> are removed.</p>
<p>If we aren’t purging the package we stop here. Note that packages
which have no <code class="docutils literal notranslate"><span class="pre">postrm</span></code> and no <code class="docutils literal notranslate"><span class="pre">conffile</span></code>s are automatically
purged when removed, as there is no difference except for the
<code class="docutils literal notranslate"><span class="pre">dpkg</span></code> status.</p>
</li>
<li><p>The <code class="docutils literal notranslate"><span class="pre">conffile</span></code>s and any backup files (<code class="docutils literal notranslate"><span class="pre">~</span></code>-files, <code class="docutils literal notranslate"><span class="pre">#*#</span></code> files,
<code class="docutils literal notranslate"><span class="pre">%</span></code>-files, <code class="docutils literal notranslate"><span class="pre">.dpkg-{old,new,tmp}</span></code>, etc.) are removed.</p></li>
<li><pre class="literal-block"><em>postrm</em> purge</pre>
<p>If this fails, the package remains in a “Config-Files” state.</p>
</li>
<li><p>The package’s file list is removed.</p></li>
</ol>
<dl class="footnote brackets">
<dt class="label" id="id8"><span class="brackets"><a class="fn-backref" href="#id1">1</a></span></dt>
<dd><p>This is so that if an error occurs, the user interrupts <code class="docutils literal notranslate"><span class="pre">dpkg</span></code> or
some other unforeseen circumstance happens you don’t leave the user
with a badly-broken package when <code class="docutils literal notranslate"><span class="pre">dpkg</span></code> attempts to repeat the
action.</p>
</dd>
<dt class="label" id="id9"><span class="brackets"><a class="fn-backref" href="#id2">2</a></span></dt>
<dd><p>This can happen if the new version of the package no longer
pre-depends on a package that had been partially upgraded.</p>
</dd>
<dt class="label" id="id10"><span class="brackets"><a class="fn-backref" href="#id3">3</a></span></dt>
<dd><p>For example, suppose packages foo and bar are “Installed” with foo
depending on bar. If an upgrade of bar were started and then aborted,
and then an attempt to remove foo failed because its <code class="docutils literal notranslate"><span class="pre">prerm</span></code> script
failed, foo’s <code class="docutils literal notranslate"><span class="pre">postinst</span> <span class="pre">abort-remove</span></code> would be called with bar only
“Half-Installed”.</p>
</dd>
<dt class="label" id="id11"><span class="brackets"><a class="fn-backref" href="#id4">4</a></span></dt>
<dd><p>This is often done by checking whether the command or facility the
<code class="docutils literal notranslate"><span class="pre">postrm</span></code> intends to call is available before calling it. For
example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="p">[</span> <span class="s2">&quot;$1&quot;</span> <span class="o">=</span> <span class="n">purge</span> <span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="p">[</span> <span class="o">-</span><span class="n">e</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">share</span><span class="o">/</span><span class="n">debconf</span><span class="o">/</span><span class="n">confmodule</span> <span class="p">];</span> <span class="n">then</span>
    <span class="o">.</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">share</span><span class="o">/</span><span class="n">debconf</span><span class="o">/</span><span class="n">confmodule</span> <span class="n">db_purge</span>
<span class="n">fi</span>
</pre></div>
</div>
<p>in <code class="docutils literal notranslate"><span class="pre">postrm</span></code> purges the <code class="docutils literal notranslate"><span class="pre">debconf</span></code> configuration for the package if
debconf is installed.</p>
</dd>
<dt class="label" id="id12"><span class="brackets"><a class="fn-backref" href="#id5">5</a></span></dt>
<dd><p>See <a class="reference internal" href="ap-flowcharts.html"><span class="doc">Maintainer script flowcharts</span></a> for flowcharts illustrating
the processes described here.</p>
</dd>
<dt class="label" id="id13"><span class="brackets"><a class="fn-backref" href="#id6">6</a></span></dt>
<dd><p>Part of the problem is due to what is arguably a bug in <code class="docutils literal notranslate"><span class="pre">dpkg</span></code>.</p>
</dd>
<dt class="label" id="id14"><span class="brackets"><a class="fn-backref" href="#id7">7</a></span></dt>
<dd><p>Historical note: Truly ancient (pre-1997) versions of <code class="docutils literal notranslate"><span class="pre">dpkg</span></code> passed
<code class="docutils literal notranslate"><span class="pre">&lt;unknown&gt;</span></code> (including the angle brackets) in this case. Even older
ones did not pass a second argument at all, under any circumstance.
Note that upgrades using such an old dpkg version are unlikely to
work for other reasons, even if this old argument behavior is handled
by your postinst script.</p>
</dd>
</dl>
</section>
</section>


            <div class="clearer"></div>
          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="index.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">6. Package maintainer scripts and installation procedure</a><ul>
<li><a class="reference internal" href="#introduction-to-package-maintainer-scripts">6.1. Introduction to package maintainer scripts</a></li>
<li><a class="reference internal" href="#maintainer-scripts-idempotency">6.2. Maintainer scripts idempotency</a></li>
<li><a class="reference internal" href="#controlling-terminal-for-maintainer-scripts">6.3. Controlling terminal for maintainer scripts</a></li>
<li><a class="reference internal" href="#exit-status">6.4. Exit status</a></li>
<li><a class="reference internal" href="#summary-of-ways-maintainer-scripts-are-called">6.5. Summary of ways maintainer scripts are called</a></li>
<li><a class="reference internal" href="#details-of-unpack-phase-of-installation-or-upgrade">6.6. Details of unpack phase of installation or upgrade</a></li>
<li><a class="reference internal" href="#details-of-configuration">6.7. Details of configuration</a></li>
<li><a class="reference internal" href="#details-of-removal-and-or-configuration-purging">6.8. Details of removal and/or configuration purging</a></li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="ch-controlfields.html"
                        title="previous chapter"><span class="section-number">5. </span>Control files and their fields</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="ch-relationships.html"
                        title="next chapter"><span class="section-number">7. </span>Declaring relationships between packages</a></p>
  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="_sources/ch-maintainerscripts.rst.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3 id="searchlabel">Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="search.html" method="get">
      <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
      <input type="submit" value="Go" />
    </form>
    </div>
</div>
<script>$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="ch-relationships.html" title="7. Declaring relationships between packages"
             >next</a> |</li>
        <li class="right" >
          <a href="ch-controlfields.html" title="5. Control files and their fields"
             >previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="index.html">Debian Policy Manual v4.6.0.1</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href=""><span class="section-number">6. </span>Package maintainer scripts and installation procedure</a></li> 
      </ul>
    </div>
    <div class="footer" role="contentinfo">
      Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 4.2.0.
    </div>
  </body>
</html>