Debian POSIX Shell Compliance in Maintainer Scripts
Debian ensures that maintainer scripts execute reliably, safely, and
quickly across diverse architectures by enforcing strict adherence to
POSIX standards for shell scripts. Debian achieves this compliance by
combining clear policy mandates, a strictly compliant default system
shell (dash), static analysis tools like
checkbashisms, and automated package validation via
Lintian. This prevents script authors from relying on shell-specific
extensions (commonly known as "bashisms") when targeting the standard
/bin/sh interpreter.
The Debian Policy Manual Requirement
Debian Policy specifically regulates the execution environment of
maintainer scripts (preinst, postinst,
prerm, and postrm). Section 10.4 of the policy
dictates that any script declaring #!/bin/sh as its
interpreter must only utilize features specified by the POSIX standard,
augmented by a strictly controlled set of historical exceptions. If a
package requires non-POSIX extensions (such as arrays, process
substitution, or non-standard conditional syntax), the script must
explicitly declare an interpreter that supports them (such as
#!/bin/bash) and depend on the corresponding package.
Switching the Default System Shell to Dash
Historically, /bin/sh pointed to /bin/bash
on most Linux distributions. Debian changed this default to
/bin/dash (the Debian Almquist Shell). Because
dash implements only POSIX specifications without GNU Bash
extensions, it serves as a strict runtime enforcement layer. If a
maintainer script uses #!/bin/sh while invoking
Bash-specific syntax, the script will immediately encounter a syntax or
execution error under dash. This runtime fragility provides
an active deterrent against non-portable scripting during development
and testing.
Static Analysis with checkbashisms
To detect compliance issues before runtime, Debian developers utilize
checkbashisms, a tool included in the
devscripts suite. The utility scans scripts marked with
#!/bin/sh against a comprehensive database of regular
expressions representing known Bashisms. Common flags detected
include:
- The use of
[[ ... ]]instead of standard[ ... ]ortestsyntax. - String comparison using
==instead of=. - Bash-style arrays (
var[0]=valor${var[@]}). - Extended parameters like
${var/search/replace}. - Non-portable options in built-in utilities, such as
echo -eorsource.
Automated Quality Assurance via Lintian
Package integration requires passing Lintian, Debian's automated package auditing tool. During package builds and archive uploads, Lintian scans maintainer scripts and triggers specific warning or error tags when non-POSIX syntax is identified:
possible-bashism-in-maintainer-script: Emitted when suspicious or non-standard syntax is flagged in/bin/shscripts.- Severity Classification: Under Debian release
criteria, a functional failure caused by a bashism in a
#!/bin/shmaintainer script is treated as a release-critical bug (severity: serious), which automatically prevents the package from migrating into the Debiantestingorstablereleases until patched.
Archive-Wide Automated Testing
Debian regularly subjects the entire package archive to rebuilds and
installation testing using automated test runners such as
piuparts and Continuous Integration (CI) testbeds.
piuparts installs, upgrades, and removes packages in a
minimal chroot where /bin/sh resolves to
dash. If a maintainer script fails due to an unhandled
POSIX violation, the test fails, logging the defect publicly and
alerting package maintainers to resolve the incompatibility.