nix icon indicating copy to clipboard operation
nix copied to clipboard

nix-shell --command doesn't work for FHS environments

Open ekmecic opened this issue 6 years ago • 8 comments

I'm scripting a tedious process I have to do to get a build for a project.The project lives in a FHS built by buildFHSUserEnv. It would be very convenient if I could pass commands to be executed in the chroot like it works with regular nix-shell environments, e.g.

nix-shell default.nix --command "make -j4 && cp some_file other_place"

Unfortunately this doesn't seem to be possible.

ekmecic avatar Sep 18 '17 14:09 ekmecic

A nix-shell with a buildFHSUserEnv does not behave like a regular nix-shell at all, unfortunately. Things like --command and --run are simply broken, even simple things like using an interactive bash are not possible. Putting bashInteractive into the targetPkgs doesn't change anything.

nioncode avatar Mar 21 '18 14:03 nioncode

Hi folks, just wondering if there's any workaround/solution to this yet?

cprussin avatar Dec 13 '18 00:12 cprussin

If you set runScript = "bash", you can run nix-shell and you get a shell in the environment. Still doesn't work with --run but it'll give you a shell. If you only ever want to run one command, you can put that as your runScript.

JohnAZoidberg avatar Sep 23 '19 08:09 JohnAZoidberg

The way I solve this problem is to make runScript an argument, then you can supply your command to that argument. e.g.

# fhs.nix
{
  pkgs ? import <nixpkgs> {},
  # This allows us to provide a command to run via `--argstr run COMMAND`.
  run ? "bash"
}:
with pkgs; (buildFHSUserEnv {
  name = "fhs";
  targetPkgs = pkgs: with pkgs; [
    curl
    git
    gnumake
  ];
  runScript = "${run}";
  profile = ''
    export SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt
    export GIT_SSL_CAINFO="$SSL_CERT_FILE"
    export LANG=C.UTF-8
  '';
}).env

You can execute your command with:

$ nix-shell --pure --argstr run "sh -c 'make -j4 && cp some_file other_place'" fhs.nix

I tend to wrap it up in a little script, fhs:

#!/usr/bin/env bash

set -euo pipefail

fhs="./fhs.nix"

function run {
  nix-shell --pure --argstr run "$*" "${fhs}"
}

if [[ $# -eq 0 ]]; then
  run bash
else
  run "$@"
fi

Usage is then:

$ ./fhs # for a bash shell in the FHS
$ ./fhs echo hi # do execute command in FHS

steshaw avatar Sep 23 '19 23:09 steshaw

I marked this as stale due to inactivity. → More info

stale[bot] avatar Feb 15 '21 14:02 stale[bot]

My workaround here is use profile to do everything directly instead of runScript & command

Following is file named test.nix (and chmod +x ed)

#!/usr/bin/env nix-shell
#! nix-shell test.nix

{ pkgs ? import <nixpkgs> {} }:

(pkgs.buildFHSUserEnv {
  name = "devbox";
  targetPkgs = pkgs: (with pkgs; [
    python38
    python38Packages.pip
    python38Packages.virtualenv
    openssl
    zlib
    stdenv.cc.cc.lib
    pythonManylinuxPackages.manylinux2014Package
  ]);
  profile = ''
    ${builtins.toString ./.}/test -g --venv ${builtins.toString ../.././.}/venv-py38
  '';
}).env

I'm not sure is there any disadvantages, but it works for me here.

Still hoping this issue can be fixed properly :)

luochen1990 avatar Jan 04 '22 07:01 luochen1990

I marked this as stale due to inactivity. → More info

stale[bot] avatar Jul 10 '22 07:07 stale[bot]

I marked this as stale due to inactivity. → More info

This is still an issue.

blitz avatar Aug 01 '22 21:08 blitz

Still very much an issue, as flake devshells don't even seem to have any way to accept arguments

cmm avatar Mar 05 '23 12:03 cmm