bash: Make interactive the default

The status quo of `bash` not being interactive is frustrating for many users,
because trying to use it interactively is just messed up, and
`bashInteractive` is not intuitive and barely discoverable.

This was brought to my (and many others) attention by @stahnma in his
[talk at CfgMgmtCamp 2025](https://cfp.cfgmgmtcamp.org/ghent2025/talk/YUVUTN/),
where he highlighted this as one of the frustrations he ran into when
learning Nix.

Why this is fine:
- No reason for not making interactive the default was given in the original commit (6c6ff6f36f), but probably it was due to the increase in closure size
- The closure size only increases by 6.9MiB (19.5%) today, with the
  added dependency on the store paths for readline and ncurses, which
  are needed on systems in almost all cases anyways
- If somebody really needs to get a more minimal system, they can use
  the newly-introduced `bashNonInteractive` instead now
- Though to apply it consistently, they'll need to do that in an
  overlay like
  ```
  final: prev: {
    bash = self.bashNonInteractive;
  }
  ```

  Or alternatively using the `system.replaceDependencies.replacements`
  NixOS option approach.

While there's also other such `*Interactive` packages that could use the
same treatment, `bash` is a great start.

This was already attempted before in
https://github.com/NixOS/nixpkgs/pull/151227, but was not continued for
unknown reason.

To avoid stdenv becoming bigger, all uses of bash in the (working)
stdenv's are changed to the explicitly non-interactive version here.

This commit will however still cause a mass rebuild for all packages (and reverse deps)
making use of the default bash.
This commit is contained in:
Silvan Mosberger
2025-02-05 00:31:46 +01:00
parent 10053c5dfd
commit e3491c9e40
13 changed files with 44 additions and 44 deletions
@@ -24,7 +24,7 @@
, zlib
# platform-specific dependencies
, bash
, bashNonInteractive
, darwin
, windows
@@ -235,7 +235,7 @@ in with passthru; stdenv.mkDerivation (finalAttrs: {
inherit nativeBuildInputs;
buildInputs = lib.optionals (!stdenv.hostPlatform.isWindows) [
bash # only required for patchShebangs
bashNonInteractive # only required for patchShebangs
] ++ buildInputs;
prePatch = optionalString stdenv.hostPlatform.isDarwin ''
@@ -329,7 +329,7 @@ in with passthru; stdenv.mkDerivation (finalAttrs: {
postPatch = optionalString (!stdenv.hostPlatform.isWindows) ''
substituteInPlace Lib/subprocess.py \
--replace-fail "'/bin/sh'" "'${bash}/bin/sh'"
--replace-fail "'/bin/sh'" "'${bashNonInteractive}/bin/sh'"
'' + optionalString mimetypesSupport ''
substituteInPlace Lib/mimetypes.py \
--replace-fail "@mime-types@" "${mailcap}"
@@ -611,7 +611,7 @@ in with passthru; stdenv.mkDerivation (finalAttrs: {
] ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
# Ensure we don't have references to build-time packages.
# These typically end up in shebangs.
pythonOnBuildForHost buildPackages.bash
pythonOnBuildForHost buildPackages.bashNonInteractive
];
separateDebugInfo = true;