2

From Why is the default shell on my Ubuntu 14.04 bash?:

On Debian derivatives, you can switch between Dash and Bash as the default /bin/sh by running dpkg-reconfigure dash as root.

Is it correct that both update-alternatives and dpkg-reconfigure can be used for changing the executable which a symlink in /bin/ links to?

If yes, for this purpose, what are the differences between update-alternatives and dpkg-reconfigure?

Thanks.

Stephen Kitt
  • 434,908
Tim
  • 101,790
  • Prior questions include https://unix.stackexchange.com/questions/408598/ , https://unix.stackexchange.com/questions/418852/ , and https://unix.stackexchange.com/questions/418985/ . – JdeBP Apr 15 '18 at 06:51

2 Answers2

5

update-alternatives can indeed be used to manage symlinks under /bin, or even anywhere else; that’s its purpose. It requires cooperating packages, or manual setup — the various alternatives need to be registered.

dpkg-reconfigure isn’t specific at all, it only runs a package’s post-installation maintainer script. So its behaviour is entirely dependent on the specific package it’s used to configure. In bash and dash’s case, the maintainer scripts handle the /bin/sh symlink, so yes, in this particular case dpkg-reconfigure is used to manage a symlink.

The reason why bash and dash don’t use update-alternatives to manage the /bin/sh is simply that when the possibility was enabled, update-alternatives wasn’t considered robust enough to be relied upon for such a sensitive file as /bin/sh. If anything ever goes wrong and /bin/sh ends up either removed, or pointing at a non-existent file, the system is rendered largely useless and hard to fix; it won’t even boot properly... So bash and dash take great care to ensure that /bin/sh is always usable. This involves some careful processing in their pre-installation “script” (which is actually a binary, to avoid pre-dependency loops), a trick involving dpkg-divert, and some last-ditch handling in their post-installation scripts. You’ll find details of the design of all this in bug #34717 (nineteen years ago).

To tell which binaries in a system are handled using alternatives, and which are handled using diversions (from maintainer scripts), you can use the corresponding tools, in particular dpkg-divert --list which will list all diversions. For update-alternatives --list you need to know the alternative group you’re interested in, but alternatives are easy to spot because they’re all symlinks to a file in /etc/alternatives.

Stephen Kitt
  • 434,908
2

The update-alternatives command requires that all alternatives register to it, in order for it to manage which alternative will get the symlink in /bin pointing to.

The alternatives system is quite flexible, as it can manage multiple symlinks at once and can handle multiple alternative implementations, possibly giving them weights that will help decide which one will be selected when more than two are installed, and will also gracefully pick the one that has the next highest weight if that one gets uninstalled.

The scheme used by dpkg-reconfigure dash uses dpkg's diversion system, where one package (bash) ships /bin/sh, but then other packages can "divert" that to override with their implementations.

dpkg's diversion system is not limited to symlinks (can also divert files) and doesn't require the main package to ship the original symlink (or file) to be modified to adopt a system such as update-alternatives.

The diversion system is not as flexible as the alternatives system, as it usually depends on packages to configure to put themselves to the top of the diversion and in many cases doesn't do any configuration at all (just installing a new package automatically diverts files from a previosly installed package, with no configuration.) These limitations also make it harder to use dpkg's diversion system to implement more than two alternatives.

filbranden
  • 21,751
  • 4
  • 63
  • 86
  • Thanks. Could you show how to change what shell is installed at /bin/sh by using update-alternatives and by using dpkg-reconfigure respectively? – Tim Apr 15 '18 at 12:09
  • Well, you can't change /bin/sh using update-alternatives unless your distribution decided to manage it using the alternatives system, which is not the case... They are using the dpkg diversion system to manage that. So, in short, there's no good way to do that using update-alternatives. – filbranden Apr 15 '18 at 15:07
  • On my Ubuntu 16.04, some symlinks under /user/bin/ are managed by update-alternatives. How can you tell what symlinks are managed by update-alternatives, and what by dpkg-reconfigure? How do you know /bin/sh is by dpkg-reconfigure not by update-alternatives in particular? – Tim Apr 15 '18 at 15:11