Hi, Due to working on installation bootstrap, I was looking into `/etc/shells`.
Introduction ============ `/etc/shells` contains valid login shells. Some programs match the configured shell of a user against this file to check whether a user is a normal user or a system users. For details on this file refer to `man 5 shells`. On Debian systems, it can be managed using the commands `add-shell` and `remove-shell` both of which are part of `debianutils`. Inconsistency ============= Some maintainer scripts take care to only run `add-shell` for initial configuration or for upgrading from an ancient version that didn't call `add-shell`. Others call `add-shell` for every invocation of `postinst`. Packages that only call `add-shell` once: * `bash` * `bash-static` * `dash` * `sash` * `tmux` Packages that only call `add-shell` during `postinst configure`: * `csh` * `elvish` * `mksh` * `screen` * `tcsh` Packages that call `add-shell` during any `postinst` invocation: * `9base` * `fish` * `ksh` * `myrescueshell` * `rc` * `xonsh` * `yash` * `zsh` * `zsh-static` In practice, all of the packages will add their shells on initial configuration. The second and third category will also add their shell on package upgrades. Arguably, doing so violates Debian policy section 10.7.3, which says that package upgrades must preserve local changes (such as removing a shell) on upgrades. Desired behaviour ================= This raises the question of what the desired semantics for `/etc/shells` are. Do we want the strict interpretation of the policy to be followed and update all those packages to conditionalize their `add-shell` invocations? Or is `/etc/shells` a simple collection of installed shells and administrators are not supposed to mess with it? The latter interpretation somewhat conflicts with our policy, so we might have to update it. If `/etc/shells` is not to be messed with, maybe it should not live inside `/etc`? Declarative packaging ===================== Editing `/etc/shells` by running a command during a maintainer script is less than ideal when it comes to declarative packaging. The goal of declarative packaging is to make reasoning about packages easier by eliminating the need for maintainer scripts as much as possible. One solution for this case could be `dpkg-trigger`. All the shell-providing packages could drop a snippet into a particular directory and `debianutils` could concatenate them into `/etc/shells`. Doing so would delete quite a number of maintainer scripts and centralize the chance for introducing bugs and inconsistencies such as the ones above into one maintainer script. I think using triggers has an obvious benefit here, but depending in the intended semantics of `/etc/shells`, implementing the part about preserving user changes may be difficult. A possible solution could be moving `/etc/shells` to `/var` and replacing it with a symbolic link when its contents match with the generated one one. For the installation bootstrap, the trigger-based solution would make any ordering issues related to `/etc/shells` fully go away. That would be quite an improvement. Helmut