/bin/bash is still impure.
if you really want a “quick and dirty”, you can always do:
nix-shell -p steam-run --run "steam-run <program>"
/bin/bash is still impure.
if you really want a “quick and dirty”, you can always do:
nix-shell -p steam-run --run "steam-run <program>"
I don’t want quick and dirty. I just want a minimum of unsolvable puzzles.
Like:
[ 85%] Generating asn1.cert.pem, coordinates.bin, ec_cert_with_ext.pem, ec_cert_crl_distribution.pem, intermediate.crl.der, intermediate.cert.pem, intermediate.ec.cert.pem, intermediate2.cert.pem, leaf.key.pem, leaf.cert.pem, leaf.ec.cert.pem, leaf.public.key.pem, leaf_modulus.hex, leaf2.cert.pem, root.crl.der, root.cert.pem, root.ec.cert.pem, root.ec.key.pem, root.ec.public.key.pem, root2.cert.pem, self_signed.cert.der, test_ec_signature, test_rsa_signature, time.txt
cd /nix/store/78rvpsgfp9g92sl30620ywr4239mwwpa-openenclave-sdk/tests/crypto/data && /nix/store/k8p54jg8ipvnfz435mayf5bnqhw4qqap-bash-4.4-p23/bin/bash -c /nix/store/myjxqm5qbx9gsq6spvcy73hac5rwj89w-source/tests/crypto/data/make-test-certs\ /nix/store/myjxqm5qbx9gsq6spvcy73hac5rwj89w-source/tests/crypto/data\ /nix/store/78rvpsgfp9g92sl30620ywr4239mwwpa-openenclave-sdk/tests/crypto/data\ –bash
/nix/store/k8p54jg8ipvnfz435mayf5bnqhw4qqap-bash-4.4-p23/bin/bash: /nix/store/myjxqm5qbx9gsq6spvcy73hac5rwj89w-source/tests/crypto/data/make-test-certs: /nix/store/6h0xx5d8wwl8zf7g4x2sjl0q4hr3nnb4-bash-interactive-4.4-p23/bin/bash: bad interpreter: No such file or directory
make[2]: *** [tests/crypto/data/CMakeFiles/crypto_test_data.dir/build.make:103: tests/crypto/data/asn1.cert.pem] Error 126
make[2]: Leaving directory ‘/nix/store/78rvpsgfp9g92sl30620ywr4239mwwpa-openenclave-sdk’
make[1]: *** [CMakeFiles/Makefile2:19204: tests/crypto/data/CMakeFiles/crypto_test_data.dir/all] Error 2
make[1]: Leaving directory ‘/nix/store/78rvpsgfp9g92sl30620ywr4239mwwpa-openenclave-sdk’
This expression works fine in nix-shell --pure but something is wrong in nix-build…
I have more details in the other post (sudden EOF)…
I’ve tried adding patchShebang everywhere but no luck.
Development:
I removed the shebang altogether and it built. Apparently patchShebangs gets confused?
--pure
makes the environment pure but does not chroot your shell (does not run it in a sandbox without file system access). If the project tries to use impure paths on the file system instead of relying on PATH
, it will be able to access them. It is a compromise between fully hermetic build environment (like the one inside nix-build) and fully impure one with access to the environment variables set by your system.
I just ran into this while trying to use emacs org babel mode with tramp; i.e. interactive “notebook style” computing.
At first it looked like a silent failure, but I eventually found env: ‘/bin/bash’: No such file or directory
in a nearby buffer.
I note this because I see plenty of discussion of interactions within a machine but not interactions between machines.
maybe related, but what’s the proper solution for things like PHP which executes /bin/sh like here https://github.com/php/php-src/blob/9bbeb0555b6b842ebd44e08510ff3f3226237544/ext/standard/proc_open.c#L1210-L1215
Patching the source file.
This is an alternative that can add arbitrary programs to /usr/bin and /bin while not hurting purity: GitHub - Mic92/envfs: Fuse filesystem that returns symlinks to executables based on the PATH of the requesting process.
envfs
looks really interesting.
Is it feasible to use a mechanism like that inside the build sandbox while also preserving purity there?
As I understand it that could work for build-time-only dependencies, which could be great to make things like build scripts run without tedious patching.
I would imagine for that use case it could be better to provide an explicit whitelist of paths that should be resolved from the derivation’s nativeBuildInputs
than to magically resolve everything. For example:
envfsResovle = [ "/bin/bash", "/usr/bin/env" ];
@Mic92 cntr
/breakpointHook
uses FUSE inside the sandbox as well, right?
It would be probably easier to add them via the sandboxPath option:
nix.sandboxPaths = ["/opt" "/usr"];
I’m a bit late, but couldn’t /bin/bash
just forward to the bash found in $PATH
? Is a sandbox really needed for purity?
Actually, since in many cases the upstream change we would require would be to replace #!/bin/bash
with #!/usr/bin/env bash
, would there be any problems with simply putting this as /bin/bash
?
#!/bin/sh
/usr/bin/env bash $@
It’s true that doing this is impure, but only as much as the #!/usr/bin/env bash
hashbang would be in the first place. I’m not overly familiar with the details and gotchas with shells and hashbangs, so I’m not sure if there are more problems I can’t foresee.
There is a pull request to add /bin/bash
to fhs-userenv:
https://github.com/NixOS/nixpkgs/pull/126448
Can someone from this thread review it? Maybe it’s fine there for purity and could solve the issue people have in this thread.
I know this is a blast from the past, but for those who find this article in the future I wanted to point out the explicit parts of the spec that are relevant here :
Applications should note that the standard PATH to the shell cannot be assumed to be either /bin/sh or /usr/bin/sh , and should be determined by interrogation of the PATH returned by getconf PATH, ensuring that the returned pathname is an absolute pathname and not a shell built-in.
https://pubs.opengroup.org/onlinepubs/9699919799/
As for env
the poster above is correct that it is not specified where the env
should be expected - my takeaway was really that #! env sh
is “closer to the spec” than #! /usr/bin/env sh
( I’m not recommending that it actually be used though, because as a practical matter it causes problems ).
Sorry to jump into this that late, but why couldn’t we turn /bin/bash
into a script that checks if a (say) NIX_IMPURE_BASH
environment variable is defined, and then
NIX_IMPURE_BASH
with the rest of the arguments (this could either be an absolute path or a path that must be resolved using $PATH
)To preserve purity NixOs forbids scripts to use /bin/bash.
The recommended procedure is to properly package your scripts…
or if you really want a quick and dirty solution run:
$ export NIX_IMPURE_BASH=bash
and try again.
This way we have best of all words:
steam-run
is not really user-friendly… if you need a program that is not already included in steam-run
you have to write your own derivation and the integration is really poor with the host system)NIX_IMPURE_BASH
globally and therefore impurities in packaged software will be quickly spotted…NIX_IMPURE_BASH
globally (this should be discouraged but of course cannot be avoided) we could for instance unset NIX_IMPURE_BASH
at the beginning of the build procedure and/or write a WARNING when the users is building their own software saying that impurities could arrive and that it is better to test the program with unset NIX_IMPURE_BASH
first.Late to the party, I’ll add another argument in favor of a principled way to get a /bin/bash file: interoperability from the outside.
I’m using NixOS in other context than bare machine: VMs, local or on the cloud, and even locally on WSL.
When external tools need to interact with my NixOS system, some of them expect bash to be callable via execvpe without a login shell.
Right now, on one of these occasion, I could make it call /run/current-system/sw/bin/bash
, but most of the time it is hard coded in the source code of the tool, which I may not have access to, and not configurable, especially on cloud platforms.
Being able to call /bin/bash
would allow me to use NixOS in more context, especially in production. Some people will tell me that I can use Y instead of X to do my thing and it is configurable/open-source, but life isn’t always that easy, I can’t always make this change (e.g. company already committed to using X and won’t change, for very good reasons).
Would it really be less principled to define system.activationScripts.binbash
by analogy to system.activationScripts.binsh
, though?
Edited to add: see nixos/modules/config/shells-environment.nix
for binsh
system.activationScripts.binbash
sounds reasonable to me, thanks for pointing this out.
I had missed @matthewbauer’s answer.
2 years later, I don’t quite understand why it wasn’t merged to nixpkgs
EDIT: spent a little more time reading the thread. I understand there can be challenges. I’m a bit saddened because in my position it gives another argument against NixOS in production.
In any case, thanks a lot!
I actually do agree with volth’s suggestion to have a list of symlinks (at least that’s how I manage my not-exactly-NixOS system).
@tbenst would you be willing to edit (into the top post) a mention of @matthewbauer’s code proposal in the thread?
Is there a good reason not to add an environment variable like in nix-ld to enable/disable /bin/bash
, while displaying an helpfull error message if this variable is disabled? It might help to detect impurities without significantly changing the user experience (it’s always possible to enable this environment variable by default).