Use the shell you launched nix shell and nix develop from #464

Open
opened 2024-08-07 03:26:34 +00:00 by poperigby · 6 comments

When running nix shell or nix develop, the shell that's used is always bash, regardless of what shell you launched it from. You can use nix-your-shell to fix this, but it would be nice if it was built-in.

Describe the solution you'd like

nix shell and nix develop should use the shell you launched them from (i.e. fish)

## Is your feature request related to a problem? Please describe. When running `nix shell` or `nix develop`, the shell that's used is always bash, regardless of what shell you launched it from. You can use [nix-your-shell](https://github.com/MercuryTechnologies/nix-your-shell) to fix this, but it would be nice if it was built-in. ## Describe the solution you'd like `nix shell` and `nix develop` should use the shell you launched them from (i.e. `fish`)
Owner

This is not trivial because you have to actually do the nix-your-shell thing which varies depending on the shell. Shell hooks and so on can define anything from functions to environment variables, in principle. Of course the average shell does a lot less, but it feels a little bit unintuitive to use a shell that will not work to actually "develop" a derivation when you run nix develop.

I agree though that this is annoying behaviour and should have a built-in fix, but I don't see that it is always sound to apply it.

This is, more than anything, showing the tension between the "debug a derivation" use case of nix develop and the "provide a dedicated dev shell" use case.

For what it's worth, I think that nix shell does not actually launch bash based on the testing I just did, but maybe I have configured something. nix-shell will launch bash for the same reason as nix develop.

This is not trivial because you have to actually *do* the nix-your-shell thing which varies depending on the shell. Shell hooks and so on can define anything from functions to environment variables, in principle. Of course the *average* shell does a lot less, but it feels a little bit unintuitive to use a shell that will not work to actually "develop" a derivation when you run `nix develop`. I agree though that this is annoying behaviour and should have a built-in fix, but I don't see that it is always sound to apply it. This is, more than anything, showing the tension between the "debug a derivation" use case of `nix develop` and the "provide a dedicated dev shell" use case. For what it's worth, I think that `nix shell` does not actually launch bash based on the testing I just did, but maybe I have configured something. `nix-shell` will launch bash for the same reason as `nix develop`.
jade added the
ux
label 2024-08-07 04:08:55 +00:00
Member

nix shell already does this. From the docs:

nix shell runs a command in an environment in which the $PATH variable provides the specified installables. If no command is specified, it starts the default shell of your user account specified by $SHELL.

So if this doesn't work for you, I assume the SHELL variable isn't set up?

When I run nix shell from zsh, it launches zsh. When I change the SHELL variable, it launches the respective shell.

 ~/.dotfiles $ nix shell nixpkgs#fish
 ~/.dotfiles $ SHELL=fish nix shell nixpkgs#jq
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
feuh@W6WFDWT3VX ~/.dotfiles (master)> nix shell nixpkgs#hello
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
feuh@W6WFDWT3VX ~/.dotfiles (master)> SHELL=bash nix shell nixpkgs#asdf

The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.
For more details, please visit https://support.apple.com/kb/HT208050.
felix:~/.dotfiles$ 

As jade said, nix develop does not use the user's shell for a good reason. It is supposed to create a reproducible environment that guarantees the presence of certain commands as well as the executing shell.

`nix shell` already does this. From [the docs](https://docs.lix.systems/manual/lix/stable/command-ref/new-cli/nix3-shell.html): > nix shell runs a command in an environment in which the $PATH variable provides the specified installables. If no command is specified, it starts the default shell of your user account specified by $SHELL. So if this doesn't work for you, I assume the `SHELL` variable isn't set up? When I run `nix shell` from zsh, it launches zsh. When I change the `SHELL` variable, it launches the respective shell. ``` ~/.dotfiles $ nix shell nixpkgs#fish ~/.dotfiles $ SHELL=fish nix shell nixpkgs#jq Welcome to fish, the friendly interactive shell Type help for instructions on how to use fish feuh@W6WFDWT3VX ~/.dotfiles (master)> nix shell nixpkgs#hello Welcome to fish, the friendly interactive shell Type help for instructions on how to use fish feuh@W6WFDWT3VX ~/.dotfiles (master)> SHELL=bash nix shell nixpkgs#asdf The default interactive shell is now zsh. To update your account to use zsh, please run `chsh -s /bin/zsh`. For more details, please visit https://support.apple.com/kb/HT208050. felix:~/.dotfiles$ ``` As jade said, `nix develop` does not use the user's shell for a good reason. It is supposed to create a reproducible environment that guarantees the presence of certain commands as well as the executing shell.
Author

Yeah, making nix develop always use bash makes sense. One problem with the way nix shell does it though. If your SHELL is set to bash, even though you use bash (because fish isn't posix compliant and can break things as a login shell), then nix shell will still use bash. That's why I think it would be better to launch the shell that the command was called from.

Yeah, making `nix develop` always use bash makes sense. One problem with the way `nix shell` does it though. If your `SHELL` is set to bash, even though you use bash (because fish isn't posix compliant and can break things as a login shell), then `nix shell` will still use bash. That's why I think it would be better to launch the shell that the command was called from.
Owner

Hm, how does anything else that shoves you in a shell environment handle this? Querying the parent process is an incredibly wrong solution so that's out. I can tell you that neovim :terminal does just use $SHELL for determining what to launch, which will have the exact problem you describe here, but you can just do whatever neovim things to alias this problem out of existence.

However, I think it is a semi-footgun to make this into a config option, since nix develop would still be bash.

Hm, how does anything else that shoves you in a shell environment handle this? Querying the parent process is an incredibly wrong solution so that's out. I can tell you that neovim `:terminal` does just use `$SHELL` for determining what to launch, which will have the exact problem you describe here, but you can just do whatever neovim things to alias this problem out of existence. **However**, I think it is a semi-footgun to make this into a config option, since `nix develop` would still be `bash`.
Owner

This is, more than anything, showing the tension between the "debug a derivation" use case of nix develop and the "provide a dedicated dev shell" use case.

You know this is a good point, maybe we should consider widening this distinction? Debugging a derivation and having an environment suitable for general development both want the build inputs the derivation needs, but the former wants exact shell hooks while the latter often only really cares about environment variables.

> This is, more than anything, showing the tension between the "debug a derivation" use case of nix develop and the "provide a dedicated dev shell" use case. You know this is a good point, maybe we should consider widening this distinction? Debugging a derivation and having an environment suitable for general development both want the build inputs the derivation needs, but the former wants exact shell hooks while the latter often only really cares about environment variables.
Member

The NixCpp team has struggled with this distinction for a long time and has recently taken the first step to allow for more different usecases here: https://github.com/NixOS/nix/pull/10807

Basically, the idea is to have separate nix dev shell and nix env shell commands, and allow for extending the nix dev and nix env groups based on different usecases. Not saying that's the best direction to take, but it's a decent option.

Hm, how does anything else that shoves you in a shell environment handle this? Querying the parent process is an incredibly wrong solution so that's out.

Is it? I just tried out poetry, and it did not care about me changing $SHELL, it always used the shell I'm actually launching it from. In their shell-detection routine they use a library called shellingham, which queries both ps and /proc for the current PID and tries to figure the shell out that way. Only if that fails will poetry fall back to $SHELL.

The NixCpp team has struggled with this distinction for a long time and has recently taken the first step to allow for more different usecases here: https://github.com/NixOS/nix/pull/10807 Basically, the idea is to have separate `nix dev shell` and `nix env shell` commands, and allow for extending the `nix dev` and `nix env` groups based on different usecases. Not saying that's the best direction to take, but it's a decent option. > Hm, how does anything else that shoves you in a shell environment handle this? Querying the parent process is an incredibly wrong solution so that's out. Is it? I just tried out poetry, and it did not care about me changing `$SHELL`, it always used the shell I'm actually launching it from. [In their shell-detection routine](https://github.com/python-poetry/poetry/blob/b6bad9c73c9e7e74a1a10df22210837a1e231ba1/src/poetry/utils/shell.py#L44C1-L69C26) they use a library called [shellingham](https://github.com/sarugaku/shellingham), which queries both ps and /proc for the current PID and tries to figure the shell out that way. Only if that fails will poetry fall back to `$SHELL`.
Sign in to join this conversation.
No milestone
No project
No assignees
4 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lix-project/lix#464
No description provided.