# Add /bin/bash to avoid unnecessary pain

**URL:** https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673
**Category:** Development
**Created:** [January 29, 2020, 1:40am UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673 "2020-01-29T01:40:27Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![tbenst](https://discourse.nixos.org/user_avatar/discourse.nixos.org/tbenst/32/1349_2.png) [@tbenst](https://discourse.nixos.org/u/tbenst)
#### Post date: [January 29, 2020, 1:40am UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/1 "2020-01-29T01:40:28Z")

</div>

I’ve been using NixOS as a daily driver for more than a year now, and I think I have enough experience to say that the lack of `/bin/bash` is a huge pain in the ass. The web is scattered with dozens of issues of NixOS users pleading with upstream to use `/usr/bin/env bash` instead. I just came across this issue on [Is it possible to use /usr/bin/env bash instead of /bin/bash? · Issue #3201 · broadinstitute/cromwell · GitHub](https://github.com/broadinstitute/cromwell/issues/3201).

Is there an argument against having `/bin/bash` that I’m not thinking of? It seems like dogmatism over pragmatism, but perhaps there’s a previous discussion that I did not find with a search.

Edit: is there any reason not to do `sudo ln -s /run/current-system/sw/bin/bash /bin/bash`?

---

<div class="post-metadata">

### Author: ![jonringer](https://discourse.nixos.org/user_avatar/discourse.nixos.org/jonringer/32/1348_2.png) [@jonringer](https://discourse.nixos.org/u/jonringer)
#### Post date: [January 29, 2020, 2:31am UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/2 "2020-01-29T02:31:44Z")

</div>

IIRC, `/bin/sh` and `/usr/bin/env` were added due to POSIX compliance.

> [@tbenst](#):
>
> Is there an argument against having `/bin/bash` that I’m not thinking of? It seems like dogmatism over pragmatism, but perhaps there’s a previous discussion that I did not find with a search.

Pretty dogmatic, but it’s a form of global system state. Could have issues with bash\_4 vs bash\_5, etc. Ultimately, most programs shouldn’t assume filepaths (Yes, I’m aware shebangs needs an absolute path).

> [@tbenst](#):
>
> Edit: is there any reason not to do `sudo ln -s /run/current-system/sw/bin/bash /bin/bash` ?

Not sure how persistent this is with `nixos-rebuild`.

If you want a quick hack, you could always do `nix-shell -p steam; steam-run <prog>`

---

<div class="post-metadata">

### Author: ![bhipple](https://discourse.nixos.org/user_avatar/discourse.nixos.org/bhipple/32/201_2.png) [@bhipple](https://discourse.nixos.org/u/bhipple)
#### Post date: [January 29, 2020, 5:18am UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/3 "2020-01-29T05:18:02Z")

</div>

It can be a pain, but most upstream maintainers are willing to accept a patch that moves them from /bin/bash to /usr/bin/env bash, and if they aren’t a great thing about Nix is that it’s trivial to patch their software 🙂 That’s the sort of patch that’s unlikely to bitrot with merge conflicts, as well.

---

<div class="post-metadata">

### Author: ![samueldr](https://discourse.nixos.org/user_avatar/discourse.nixos.org/samueldr/32/6_2.png) [@samueldr](https://discourse.nixos.org/u/samueldr)
#### Post date: [January 29, 2020, 6:27am UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/4 "2020-01-29T06:27:13Z")

</div>

It’s not even a NixOS-specific issue. This affects some BSDs too, where `bash` is not in `/bin/`.

---

<div class="post-metadata">

### Author: ![tbenst](https://discourse.nixos.org/user_avatar/discourse.nixos.org/tbenst/32/1349_2.png) [@tbenst](https://discourse.nixos.org/u/tbenst)
#### Post date: [January 29, 2020, 6:45am UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/5 "2020-01-29T06:45:13Z")

</div>

> [@bhipple](#):
>
> a great thing about Nix is that it’s trivial to patch their software

Unfortunately it’s not always that simple. For example, in the issue I linked it’s a .jar file, which as I understand [means re-compiling from scratch](https://stackoverflow.com/questions/5069539/is-there-are-way-to-patch-jar-files). My symbolic link was a few second fix, while packaging this software for NixOS would take me at least an hour. Upstream maintainers are [often incredulous](https://github.com/RcppCore/RcppArmadillo/issues/15) when this issue is reported. Even with upstream willingness, there are often valid reasons not to switch to `/usr/bin/env bash`–namely lack of support for multiple arguments.

> [@jonringer](#):
>
> IIRC, `/bin/sh` and `/usr/bin/env` were added due to POSIX compliance.

POSIX specifies that [env should exist](https://pubs.opengroup.org/onlinepubs/9699919799/), but not the path itself, so `/usr/bin/env` is usually present, just as `/bin/bash` is usually present.

A quick search shows more than [5,000 issues on github](https://github.com/search?q=%2Fbin%2Fbash+nixos&type=Issues) for NixOS & `/bin/bash`. It seems like this is just a waste of everyone’s time with no derived benefit, outside of some noble feeling of purity.

---

<div class="post-metadata">

### Author: ![KoviRobi](https://discourse.nixos.org/user_avatar/discourse.nixos.org/kovirobi/32/33578_2.png) [@KoviRobi](https://discourse.nixos.org/u/KoviRobi)
#### Post date: [January 29, 2020, 12:16pm UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/6 "2020-01-29T12:16:54Z")

</div>

Java `.jar` files are just archives (Java ARchive) so extract, change and repack, but the problem in this case might require at least recompiling that file, as the string is embedded in a compiled `.class` file (as opposed to say a text file in a `.jar` archive).

But I do also feel like we might be more than a bit annoying with not having `/bin/bash`. However, I think if we do end up with having ‘/bin/bash’, it needs to be compatible with the macOS bash which is version 3.2.57 (due to licensing issues with newer bash)

---

<div class="post-metadata">

### Author: ![tbenst](https://discourse.nixos.org/user_avatar/discourse.nixos.org/tbenst/32/1349_2.png) [@tbenst](https://discourse.nixos.org/u/tbenst)
#### Post date: [January 29, 2020, 5:10pm UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/7 "2020-01-29T17:10:38Z")

</div>

I think a good design decision would be to have a user configurable `/bin/bash`. That way those that care for macOS compatibility could choose 3, most of us could choose 5, and those that were so inclined could elect to have none at all.

I wholeheartedly like and appreciate that NixOS’s /bin is so sparse, but bash is a special case used by many in the same way as `/bin/sh`

---

<div class="post-metadata">

### Author: ![KoviRobi](https://discourse.nixos.org/user_avatar/discourse.nixos.org/kovirobi/32/33578_2.png) [@KoviRobi](https://discourse.nixos.org/u/KoviRobi)
#### Post date: [January 29, 2020, 6:34pm UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/8 "2020-01-29T18:34:22Z")

</div>

The problem with that is then we won’t be reproducible, e.g. suppose we have `/bin/bash` in one computer, and none in another. If the package maintainer uses `/bin/bash` and the user doesn’t then the package won’t work. Worse with multiple versions, supposing (this is a silly conjecture but the principle holds) that the only terminal emulator requires bash 3 at runtime, and the only text editor requires bash 5 at runtime and both are incompatible… In reality it’s probably not this serious, but we still want to avoid stuff like this.

Caveat: We probably do some of this by using `/bin/sh` but perhaps in theory only rely on a minimum compatible set of features?

---

<div class="post-metadata">

### Author: ![tbenst](https://discourse.nixos.org/user_avatar/discourse.nixos.org/tbenst/32/1349_2.png) [@tbenst](https://discourse.nixos.org/u/tbenst)
#### Post date: [January 29, 2020, 6:54pm UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/9 "2020-01-29T18:54:09Z")

</div>

In reality the Bash API is highly stable and backwards compatible. The vast majority of scripts that ran on [bash 4.4 will also run on Bash 5.0](https://tiswww.case.edu/php/chet/bash/NEWS). I’ve personally never encountered a situation where a script didn’t run because it was designed for an earlier version of bash. You do occasionally hear issues with mac users, but that’s a very different situation of being on an old version of bash lacking features used in modern scripts.

On the reproducibility spectrum between instruction set versions and python versions, bash is much closer to instruction sets.

---

<div class="post-metadata">

### Author: ![matthewbauer](https://discourse.nixos.org/user_avatar/discourse.nixos.org/matthewbauer/32/31_2.png) [@matthewbauer](https://discourse.nixos.org/u/matthewbauer)
#### Post date: [January 29, 2020, 7:39pm UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/10 "2020-01-29T19:39:38Z")

</div>

Here’s a module do this in a NixOS configuration, in the same way /usr/bin/env works. Perhaps we should consider it for NixOS?

```auto
{ config, lib, pkgs, ... }:

with lib;

{

  options = {
    environment.binbash = mkOption {
      default = null;
      type = types.nullOr types.path;
      description = ''
        Include a /bin/bash in the system.
      '';
    };
  };

  config = {

    system.activationScripts.binbash = if config.environment.binbash != null
      then ''
        mkdir -m 0755 -p /bin
        ln -sfn ${config.environment.usrbinenv} /bin/.bash.tmp
        mv /bin/.bash.tmp /usr/bin/bash # atomically replace /usr/bin/env
      ''
      else ''
        rm -f /bin/bash
        rmdir -p /bin || true
      '';

  };

}

```

---

<div class="post-metadata">

### Author: ![KoviRobi](https://discourse.nixos.org/user_avatar/discourse.nixos.org/kovirobi/32/33578_2.png) [@KoviRobi](https://discourse.nixos.org/u/KoviRobi)
#### Post date: [January 29, 2020, 9:36pm UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/11 "2020-01-29T21:36:07Z")

</div>

True, but the mac issue will happen, especially if we make the bash version selectable. What I am saying, is that if we make this a thing, we then have to make it a thing for all installations with the same bash version[1]. And we need version compatibility both ways[1]. Otherwise I could write a derivation that works on my system because I have `/bin/bash`, but won’t work on your system if you don’t have `/bin/bash` (either build time or run time)!

[1] Okay, the same version thing is an impurity we already have, i.e. the caveat of `/bin/sh` can be different on non-NixOS installations. E.g. if I do

```auto
$ nix-shell --pure -A bash # or something
nix-shell $ /bin/sh --version
# I get 3.2.57(1)-release on mac
# I get 4.4.23(1)-release on NixOS 19.09

```

---

<div class="post-metadata">

### Author: ![tbenst](https://discourse.nixos.org/user_avatar/discourse.nixos.org/tbenst/32/1349_2.png) [@tbenst](https://discourse.nixos.org/u/tbenst)
#### Post date: [January 30, 2020, 6:41am UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/12 "2020-01-30T06:41:51Z")

</div>

@matthewbauer that’s awesome, thanks for making!

@KoviRobi we could still require that submissions to nixpkgs do not depend on `/bin/bash` for purity reasons if we want users to be able to ‘opt-in’ to `/bin/bash` on NixOS without forcing it on everyone.

Otherwise, defaulting to Bash 4.4 seems reasonable given that all of nixpkgs uses this. `bash_5` is not used anywhere, and Bash 3 is not in nixpkgs.

---

<div class="post-metadata">

### Author: ![7c6f434c](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/7/8e7dd6/32.png) [@7c6f434c](https://discourse.nixos.org/u/7c6f434c)
#### Post date: [January 30, 2020, 8:22am UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/13 "2020-01-30T08:22:00Z")

</div>

> @KoviRobi we could still require that submissions to nixpkgs do not depend on `/bin/bash` for purity reasons if we want users to be able to ‘opt-in’ to `/bin/bash` on NixOS without forcing it on everyone.

The problem is that then PR feedback from people who opted in to having `/bin/bash` will become slightly suspect, sometimes without the person doing the testing realising it.

---

<div class="post-metadata">

### Author: ![aanderse](https://discourse.nixos.org/user_avatar/discourse.nixos.org/aanderse/32/1420_2.png) [@aanderse](https://discourse.nixos.org/u/aanderse)
#### Post date: [January 30, 2020, 11:20am UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/14 "2020-01-30T11:20:27Z")

</div>

Completely agreed. One thing I really appreciate about NixOS is reproducibility on bug reports. I think `/bin/bash` and things like that which compromise reproducibility would have such a big impact that in the worst possible way. It’s almost as if NixOS becomes 2 distros at that point.

---

<div class="post-metadata">

### Author: ![tbenst](https://discourse.nixos.org/user_avatar/discourse.nixos.org/tbenst/32/1349_2.png) [@tbenst](https://discourse.nixos.org/u/tbenst)
#### Post date: [January 30, 2020, 4:20pm UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/15 "2020-01-30T16:20:43Z")

</div>

Perhaps there’s a way for `useSandbox` to exclude /bin/bash using a bind mount or otherwise?

---

<div class="post-metadata">

### Author: ![KoviRobi](https://discourse.nixos.org/user_avatar/discourse.nixos.org/kovirobi/32/33578_2.png) [@KoviRobi](https://discourse.nixos.org/u/KoviRobi)
#### Post date: [January 30, 2020, 5:55pm UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/16 "2020-01-30T17:55:12Z")

</div>

Sure, but then it still applies for a program’s runtime, should that use `/bin/bash`. Arguably we should have replaced all `/bin/bash` instances in the `fixupPhase`.

---

<div class="post-metadata">

### Author: ![qyliss](https://discourse.nixos.org/user_avatar/discourse.nixos.org/qyliss/32/34285_2.png) [@qyliss](https://discourse.nixos.org/u/qyliss)
#### Post date: [January 30, 2020, 7:27pm UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/17 "2020-01-30T19:27:04Z")

</div>

> In reality the Bash API is highly stable and backwards compatible. The  
> vast majority of scripts that ran on [bash 4.4 will also run on Bash  
> 5.0](https://tiswww.case.edu/php/chet/bash/NEWS). I’ve personally  
> never encountered a situation where a script didn’t run because it was  
> designed for an earlier version of bash.

I have, and it was in fact the Nixpkgs stdenv, which doesn’t work (or  
didn’t at the time, with Bash 5).

---

<div class="post-metadata">

### Author: ![lilyball](https://discourse.nixos.org/user_avatar/discourse.nixos.org/lilyball/32/939_2.png) [@lilyball](https://discourse.nixos.org/u/lilyball)
#### Post date: [January 31, 2020, 7:46am UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/18 "2020-01-31T07:46:28Z")

</div>

> [@tbenst](#):
>
> Perhaps there’s a way for `useSandbox` to exclude /bin/bash using a bind mount or otherwise?

We actually need to go the other way and explicitly allow `/bin/bash` in the sandbox on macOS in order to fix sandbox compatibility with macOS Catalina as `/bin/sh` on Catalina now executes `/bin/bash` (it’s got a mechanism by which it can execute `bash` or `zsh` depending on certain other global configuration; if that other config is unreachable, e.g. because the sandbox is on, it defaults to `/bin/bash`).

See [darwin: DEFAULT\_ALLOWED\_IMPURE\_PREFIXES needs to include /bin/bash on macOS 10.15 · Issue #3223 · NixOS/nix · GitHub](https://github.com/NixOS/nix/issues/3223) for more info.

---

<div class="post-metadata">

### Author: ![Melkor333](https://discourse.nixos.org/user_avatar/discourse.nixos.org/melkor333/32/3944_2.png) [@Melkor333](https://discourse.nixos.org/u/Melkor333)
#### Post date: [February 1, 2020, 10:01am UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/19 "2020-02-01T10:01:36Z")

</div>

eew, that‘s kinda disgusting. So that means `#!/bin/sh` doesn‘t necessarily mean a script needs to be strictly POSIX-compliant?

Anyway it would be great if there was a way to restrict anything in `/nix` from touching `/bin/bash`, while stuff anywhere else can use it.  
Maybe make `/bin/bash` a wrapper script which does something like

```auto
if [comesfromnix]; then
  echo "programs from the nix store aren't allowed to use this file, please patch the code!"
  exit 1
fi
/run/current-system/sw/bin/bash "$@"

```

This could also easily be extended to e.g. warn the user when this wrapper is used for the first time…

---

<div class="post-metadata">

### Author: ![lilyball](https://discourse.nixos.org/user_avatar/discourse.nixos.org/lilyball/32/939_2.png) [@lilyball](https://discourse.nixos.org/u/lilyball)
#### Post date: [February 1, 2020, 5:37pm UTC](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673/20 "2020-02-01T17:37:28Z")

</div>

> [@Melkor333](#):
>
> eew, that‘s kinda disgusting. So that means `#!/bin/sh` doesn‘t necessarily mean a script needs to be strictly POSIX-compliant?

When `/bin/sh` invokes `/bin/bash` on macOS it still does so with `argv[0] == "sh"`, meaning bash still runs in POSIX sh mode.

Edit: I also forgot to mention, on macOS 10.14 and below, `/bin/sh` is literally just `bash` with a different name (for some reason it’s 64 bytes larger than `/bin/bash` though). You can verify this with `/bin/sh -c 'echo $BASH_VERSION'`. So what macOS 10.15 is doing now isn’t functionally different except in that the sandbox needs to allow access to `/bin/bash`.

[Next page](https://discourse.nixos.org/t/add-bin-bash-to-avoid-unnecessary-pain/5673.md?page=2)
