{
	"id": "7e9dd86f-9467-4570-9dba-53e41a10a1f0",
	"created_at": "2026-04-06T00:21:44.994105Z",
	"updated_at": "2026-04-10T03:21:17.50334Z",
	"deleted_at": null,
	"sha1_hash": "3443ff364b6825ca816c18392c6b52ab2073313b",
	"title": "6. Package maintainer scripts and installation procedure — Debian Policy Manual v4.7.4.1",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 119916,
	"plain_text": "6. Package maintainer scripts and installation procedure — Debian\r\nPolicy Manual v4.7.4.1\r\nArchived: 2026-04-05 18:24:14 UTC\r\n6.1. Introduction to package maintainer scripts\r\nIt is possible to supply scripts as part of a package which the package management system will run for you when\r\nyour package is installed, upgraded or removed.\r\nThese scripts are the package metadata files preinst , postinst , prerm and postrm . They must be proper\r\nexecutable files; if they are scripts (which is recommended), they must start with the usual #! convention. They\r\nshould be readable and executable by anyone, and must not be world-writable.\r\nThe package management system looks at the exit status from these scripts. It is important that they exit with a\r\nnon-zero status if there is an error, so that the package management system can stop its processing. For shell\r\nscripts this means that you almost always need to use set -e (this is usually true when writing shell scripts, in\r\nfact). It is also important, of course, that they exit with a zero status if everything went well.\r\nAdditionally, packages interacting with users using debconf in the postinst script should install a config\r\nscript as a package metadata file. See Prompting in maintainer scripts for details.\r\nWhen a package is upgraded a combination of the scripts from the old and new packages is called during the\r\nupgrade procedure. If your scripts are going to be at all complicated you need to be aware of this, and may need to\r\ncheck the arguments to your scripts.\r\nBroadly speaking the preinst is called before (a particular version of) a package is unpacked, and the\r\npostinst afterwards; the prerm before (a version of) a package is removed and the postrm afterwards.\r\nPrograms called from maintainer scripts should not normally have a path prepended to them. Before installation is\r\nstarted, the package management system checks to see if the programs ldconfig , start-stop-daemon , and\r\nupdate-rc.d can be found via the PATH environment variable. Those programs, and any other program that one\r\nwould expect to be in the PATH , should thus be invoked without an absolute pathname. Maintainer scripts should\r\nalso not reset the PATH , though they might choose to modify it by prepending or appending package-specific\r\ndirectories. These considerations really apply to all shell scripts.\r\n6.2. Maintainer scripts idempotency\r\nIt is necessary for the error recovery procedures that the scripts be idempotent. This means that if it is run\r\nsuccessfully, and then it is called again, it doesn’t bomb out or cause any harm, but just ensures that everything is\r\nthe way it ought to be. If the first call failed, or aborted half way through for some reason, the second call should\r\nmerely do the things that were left undone the first time, if any, and exit with a success status if everything is OK.\r\n[1]\r\nhttps://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#s-mscriptsinstact\r\nPage 1 of 10\n\n6.3. Controlling terminal for maintainer scripts\r\nMaintainer scripts are not guaranteed to run with a controlling terminal and may not be able to interact with the\r\nuser. They must be able to fall back to noninteractive behavior if no controlling terminal is available. Maintainer\r\nscripts that prompt via a program conforming to the Debian Configuration Management Specification (see\r\nPrompting in maintainer scripts) may assume that program will handle falling back to noninteractive behavior.\r\nFor high-priority prompts without a reasonable default answer, maintainer scripts may abort if there is no\r\ncontrolling terminal. However, this situation should be avoided if at all possible, since it prevents automated or\r\nunattended installs. In most cases, users will consider this to be a bug in the package.\r\n6.4. Exit status\r\nEach script must return a zero exit status for success, or a nonzero one for failure, since the package management\r\nsystem looks for the exit status of these scripts and determines what action to take next based on that datum.\r\n6.5. Summary of ways maintainer scripts are called\r\nWhat follows is a summary of all the ways in which maintainer scripts may be called along with what facilities\r\nthose scripts may rely on being available at that time. Script names preceded by new- are the scripts from the new\r\nversion of a package being installed, upgraded to, or downgraded to. Script names preceded by old- are the scripts\r\nfrom the old version of a package that is being upgraded from or downgraded from.\r\nThe preinst script may be called in the following ways:\r\nnew-preinst install\r\nnew-preinst install old-version new-version\r\nnew-preinst upgrade old-version new-version\r\nThe package will not yet be unpacked, so the preinst script cannot rely on any files included in its\r\npackage. Only essential packages and pre-dependencies ( Pre-Depends ) may be assumed to be\r\navailable. Pre-dependencies will have been configured at least once, but at the time the preinst is\r\ncalled 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.\r\nold-preinst abort-upgrade new-version\r\nCalled during error handling of an upgrade that failed after unpacking the new package because the\r\npostrm upgrade action failed. The unpacked files may be partly from the new version or partly missing,\r\nso 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\r\n“Half-Installed” if an upgrade of the pre-dependency failed. [2]\r\nThe postinst script may be called in the following ways:\r\nhttps://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#s-mscriptsinstact\r\nPage 2 of 10\n\npostinst configure most-recently-configured-version\r\nThe files contained in the package will be unpacked. All package dependencies will at least be\r\n“Unpacked”. If there are no circular dependencies involved, all package dependencies will be configured.\r\nFor behavior in the case of circular dependencies, see the discussion in Binary Dependencies - Depends,\r\nRecommends, Suggests, Enhances, Pre-Depends.\r\nold-postinst abort-upgrade new-version\r\nconflictor's-postinst abort-remove in-favour package new-version\r\npostinst abort-remove\r\ndeconfigured's-postinst abort-deconfigure in-favour failed-install-package version [ removing conflicting-package version ]\r\nThe 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\r\nbe configured or even fully unpacked in some error situations. [3] The postinst should still attempt\r\nany actions for which its dependencies are required, since they will normally be available, but consider\r\nthe correct error handling approach if those actions fail. Aborting the postinst action if commands or\r\nfacilities from the package dependencies are not available is often the best approach.\r\nThe prerm script may be called in the following ways:\r\nprerm remove\r\nold-prerm upgrade new-version\r\nconflictor's-prerm remove in-favour package new-version\r\ndeconfigured's-prerm deconfigure in-favour package-being-installed version [removing conflicting-package\r\nversion]\r\nThe package whose prerm is being called will be at least “Half-Installed”. All package dependencies\r\nwill at least be “Half-Installed” and will have previously been configured and not removed. If there was\r\nno error, all dependencies will at least be “Unpacked”, but these actions may be called in various error\r\nstates where dependencies are only “Half-Installed” due to a partial upgrade.\r\nnew-prerm failed-upgrade old-version new-version\r\nCalled during error handling when prerm upgrade fails. The new package will not yet be unpacked, and\r\nall the same constraints as for preinst upgrade apply.\r\nThe postrm script may be called in the following ways:\r\npostrm remove\r\npostrm purge\r\nhttps://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#s-mscriptsinstact\r\nPage 3 of 10\n\nold-postrm upgrade new-version\r\ndisappearer's-postrm disappear overwriter overwriter-version\r\nThe postrm script is called after the package’s files have been removed or replaced. The package\r\nwhose postrm is being called may have previously been deconfigured and only be “Unpacked”, at\r\nwhich point subsequent package changes do not consider its dependencies. Therefore, all postrm\r\nactions must only rely on essential packages and must gracefully skip any actions that require the\r\npackage’s dependencies if those dependencies are unavailable. [4]\r\nnew-postrm failed-upgrade old-version new-version\r\nCalled when the old postrm upgrade action fails. The new package will be unpacked, but only essential\r\npackages and pre-dependencies can be relied on. Pre-dependencies will either be configured or will be\r\n“Unpacked” or “Half-Configured” but previously had been configured and was never removed.\r\nnew-postrm abort-install\r\nnew-postrm abort-install old-version new-version\r\nnew-postrm abort-upgrade old-version new-version\r\nCalled before unpacking the new package as part of the error handling of preinst failures. May\r\nassume the same state as preinst can assume.\r\n6.6. Details of unpack phase of installation or upgrade\r\nThe procedure on installation/upgrade/overwrite/disappear (i.e., when running dpkg --unpack , or the unpack\r\nstage of dpkg --install ) is as follows. [5] In each case, if a major error occurs (unless listed below) the actions\r\nare, in general, run backwards - this means that the maintainer scripts are run with different arguments in reverse\r\norder. These are the “error unwind” calls listed below.\r\n1. Notify the currently installed package:\r\n1. If a version of the package is already “Installed”, call\r\nold-prerm upgrade new-version\r\n2. If the script runs but exits with a non-zero exit status, dpkg will attempt:\r\nnew-prerm failed-upgrade old-version new-version\r\nIf this works, the upgrade continues. If this does not work, the error unwind:\r\nold-postinst abort-upgrade new-version\r\nhttps://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#s-mscriptsinstact\r\nPage 4 of 10\n\nIf this works, then the old-version is “Installed”, if not, the old version is in a “Half-Configured”\r\nstate.\r\n2. If a “conflicting” package is being removed at the same time, or if any package will be broken (due to\r\nBreaks ):\r\n1. If --auto-deconfigure is specified, call, for each package to be deconfigured due to Breaks :\r\ndeconfigured's-prerm deconfigure \\\r\n in-favour package-being-installed version\r\nError unwind:\r\ndeconfigured's-postinst abort-deconfigure \\\r\n in-favour package-being-installed-but-failed version\r\nThe deconfigured packages are marked as requiring configuration, so that if --install is used\r\nthey will be configured again if possible.\r\n2. If any packages depended on a conflicting package being removed and --auto-deconfigure is\r\nspecified, call, for each such package:\r\ndeconfigured's-prerm deconfigure \\\r\n in-favour package-being-installed version \\\r\n removing conflicting-package version\r\nError unwind:\r\ndeconfigured's-postinst abort-deconfigure \\\r\n in-favour package-being-installed-but-failed version \\\r\n removing conflicting-package version\r\nThe deconfigured packages are marked as requiring configuration, so that if --install is used\r\nthey will be configured again if possible.\r\n3. To prepare for removal of each conflicting package, call:\r\nconflictor's-prerm remove \\\r\n in-favour package new-version\r\nError unwind:\r\nhttps://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#s-mscriptsinstact\r\nPage 5 of 10\n\nconflictor's-postinst abort-remove \\\r\n in-favour package new-version\r\n3. Run the preinst of the new package:\r\n1. If the package is being upgraded, call:\r\nnew-preinst upgrade old-version new-version\r\nIf this fails, we call:\r\nnew-postrm abort-upgrade old-version new-version\r\n1. If that works, then\r\nold-postinst abort-upgrade new-version\r\nis called. If this works, then the old version is in an “Installed” state, or else it is left in an\r\n“Unpacked” state.\r\n2. If it fails, then the old version is left in an “Half-Installed” state.\r\n2. Otherwise, if the package had some configuration files from a previous version installed (i.e., it is in\r\nthe “Config-Files” state):\r\nnew-preinst install old-version new-version\r\nError unwind:\r\nnew-postrm abort-install old-version new-version\r\nIf this fails, the package is left in a “Half-Installed” state, which requires a reinstall. If it works, the\r\npackages is left in a “Config-Files” state.\r\n3. Otherwise (i.e., the package was completely purged):\r\nnew-preinst install\r\nError unwind:\r\nnew-postrm abort-install\r\nhttps://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#s-mscriptsinstact\r\nPage 6 of 10\n\nIf the error-unwind fails, the package is in a “Half-Installed” phase, and requires a reinstall. If the\r\nerror unwind works, the package is in the “Not-Installed” state.\r\n4. The new package’s files are unpacked, overwriting any that may be on the system already, for example any\r\nfrom the old version of the same package or from another package. Backups of the old files are kept\r\ntemporarily, and if anything goes wrong the package management system will attempt to put them back as\r\npart of the error unwind.\r\nIt is an error for a package to contain files which are on the system in another package, unless Replaces\r\nis used (see Overwriting files and replacing packages - Replaces).\r\nIt is a more serious error for a package to contain a plain file or other kind of non-directory where another\r\npackage has a directory (again, unless Replaces is used). This error can be overridden if desired using --\r\nforce-overwrite-dir , but this is not advisable.\r\nPackages which overwrite each other’s files produce behavior which, though deterministic, is hard for the\r\nsystem administrator to understand. It can easily lead to “missing” programs if, for example, a package is\r\nunpacked which overwrites a file from another package, and is then removed again. [6]\r\nA directory will never be replaced by a symbolic link to a directory or vice versa; instead, the existing state\r\n(symlink or not) will be left alone and dpkg will follow the symlink if there is one.\r\n5. If the package is being upgraded:\r\n1. Call:\r\nold-postrm upgrade new-version\r\n2. If this fails, dpkg will attempt:\r\nnew-postrm failed-upgrade old-version new-version\r\nIf this works, installation continues. If not, Error unwind:\r\nold-preinst abort-upgrade new-version\r\nIf this fails, the old version is left in a “Half-Installed” state. If it works, dpkg now calls:\r\nnew-postrm abort-upgrade old-version new-version\r\nIf this fails, the old version is left in a “Half-Installed” state. If it works, dpkg now calls:\r\nold-postinst abort-upgrade new-version\r\nhttps://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#s-mscriptsinstact\r\nPage 7 of 10\n\nIf this fails, the old version is in an “Unpacked” state.\r\nThis is the point of no return. If dpkg gets this far, it won’t back off past this point if an error occurs. This\r\nwill leave the package in a fairly bad state, which will require a successful re-installation to clear up, but\r\nit’s when dpkg starts doing things that are irreversible.\r\n6. Any files which were in the old version of the package but not in the new are removed.\r\n7. The new file list replaces the old.\r\n8. The new maintainer scripts replace the old.\r\n9. Any packages all of whose files have been overwritten during the installation, and which aren’t required\r\nfor dependencies, are considered to have been removed. For each such package\r\n1. dpkg calls:\r\ndisappearer's-postrm disappear \\\r\n overwriter overwriter-version\r\n2. The package’s maintainer scripts are removed.\r\n3. It is noted in the status database as being in a sane state, namely “Not-Installed” (any conffiles it\r\nmay have are ignored, rather than being removed by dpkg ). Note that disappearing packages do\r\nnot have their prerm called, because dpkg doesn’t know in advance that the package is going to\r\nvanish.\r\n10. Any files in the package we’re unpacking that are also listed in the file lists of other packages are removed\r\nfrom those lists. (This will lobotomize the file list of the “conflicting” package if there is one.)\r\n11. The backup files made during installation, above, are deleted.\r\n12. The new package’s status is now sane, and recorded as “Unpacked”.\r\nHere is another point of no return: if the conflicting package’s removal fails we do not unwind the rest of\r\nthe installation. The conflicting package is left in a half-removed limbo.\r\n13. If there was a conflicting package we go and do the removal actions (described below), starting with the\r\nremoval of the conflicting package’s files (any that are also in the package being unpacked have already\r\nbeen removed from the conflicting package’s file list, and so do not get removed now).\r\n6.7. Details of configuration\r\nWhen we configure a package (this happens with dpkg --install and dpkg --configure ), we first update any\r\nconffile s and then call:\r\nhttps://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#s-mscriptsinstact\r\nPage 8 of 10\n\npostinst configure most-recently-configured-version\r\nNo attempt is made to unwind after errors during configuration. If the configuration fails, the package is in a\r\n“Half-Configured” state, and an error message is generated.\r\nIf there is no most recently configured version dpkg will pass a null argument. [7]\r\n6.8. Details of removal and/or configuration purging\r\n1. prerm remove\r\nIf prerm fails during replacement due to conflict\r\nconflictor's-postinst abort-remove \\\r\n in-favour package new-version\r\nOr else we call:\r\npostinst abort-remove\r\nIf this fails, the package is in a “Half-Configured” state, or else it remains “Installed”.\r\n2. The package’s files are removed (except conffile s).\r\n3. postrm remove\r\nIf it fails, there’s no error unwind, and the package is in an “Half-Installed” state.\r\n4. All the maintainer scripts except the postrm are removed.\r\nIf we aren’t purging the package we stop here. Note that packages which have no postrm and no\r\nconffile s are automatically purged when removed, as there is no difference except for the dpkg status.\r\n5. The conffile s and any backup files ( ~ -files, #*# files, % -files, .dpkg-{old,new,tmp} , etc.) are\r\nremoved.\r\n6. postrm purge\r\nIf this fails, the package remains in a “Config-Files” state.\r\n7. The package’s file list is removed.\r\nhttps://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#s-mscriptsinstact\r\nPage 9 of 10\n\nSource: https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#s-mscriptsinstact\r\nhttps://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#s-mscriptsinstact\r\nPage 10 of 10",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#s-mscriptsinstact"
	],
	"report_names": [
		"ch-maintainerscripts.html#s-mscriptsinstact"
	],
	"threat_actors": [],
	"ts_created_at": 1775434904,
	"ts_updated_at": 1775791277,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/3443ff364b6825ca816c18392c6b52ab2073313b.pdf",
		"text": "https://archive.orkl.eu/3443ff364b6825ca816c18392c6b52ab2073313b.txt",
		"img": "https://archive.orkl.eu/3443ff364b6825ca816c18392c6b52ab2073313b.jpg"
	}
}