1

I would like to initiate a nix-shell (if unfamiliar with Nix), this can be thought of as a bashs hell that loads a particular environment, somewhat expensively). Once initiated as a separate process, I'd like to be able to send commands to that shell and retrieve the results. There is the potential for some complexity here related to concurrency issues, but I thought shelly might be able to simply handle it like this:

#!/usr/bin/env stack
{- stack script --nix --resolver lts-14.27
     --package async
     --package shelly
-}

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ExtendedDefaultRules #-}
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
  
import Shelly

main :: IO ()
main = shelly $ do
  run_ "nix-shell" ["-p", "cargo"]
  run_ "cargo" []

In the first run_, we initiate a shell that has the cargo command available, which we should then be able to run using the second call to run_. However, this results in an error where the PATH does not seem to be correct - strangely it no longer containers even nix-shell in the path.

I'd be open to suggestions on how to do this using various approaches, not necessarily with shelly.

bbarker
  • 11,636
  • 9
  • 38
  • 62
  • 1
    Environment variables only propagate from parent process to child process, not the other way around, so the first `cargo` inherits them from `nix-shell`, which works, whereas the second inherits them from your Haskell program, which is unaware of what `nix-shell` loaded before it. If your program always requires Nix, you may be better of with a `#!/usr/bin/env nix-shell` shebang. If Nix is optional, you could run `nix-shell -p cargo env`, parse the output and use `System.Environment.setEnv` so that subsequent commands have that environment. Lorri does something similar. – Robert Hensing Mar 19 '21 at 10:59
  • I like the approaches you outlined, thanks. One issue remains - it seems that `stack` may be "trashing" the environment, since `nix-shell` is not in it afterwards. I.e., in the ambient shell environment, `/run/current-system/sw/bin` is in the `PATH`, but not in the `PATH` of the Haskell process as shown above (I checked this by doing `envAll <- get_env_all` and then `liftIO $ putStrLn $ show envAll` in the shelly script) – bbarker Mar 19 '21 at 19:32
  • 1
    Perhaps you could run `nix-shell` as the outer process wrapper and stack as the inner one? See https://discourse.nixos.org/t/using-nix-shell-shebang-with-cabal-stack/3743/3?u=roberth – Robert Hensing Mar 22 '21 at 10:50

0 Answers0