Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Still cannot set fish as default shell #1237

Open
nalzok opened this issue Dec 26, 2024 · 8 comments
Open

Still cannot set fish as default shell #1237

nalzok opened this issue Dec 26, 2024 · 8 comments

Comments

@nalzok
Copy link

nalzok commented Dec 26, 2024

This is probably a regression of #328, #779, and #811, which were considered fixed:

Updating /etc/shells manually or via environment.shells should no longer be necessary since #1118 as long as you set the shell you want to use with users.users.<user>.shell = pkgs.fish;

However, the following configuration doesn't seem to work on a fresh copy of macOS 15.2 (24C101).

{
  description = "Example nix-darwin system flake";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    nix-darwin.url = "github:LnL7/nix-darwin";
    nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs = inputs@{ self, nix-darwin, nixpkgs }:
  let
    configuration = { pkgs, ... }: {
      # List packages installed in system profile. To search by name, run:
      # $ nix-env -qaP | grep wget
      environment.systemPackages = [
      ];

      # Necessary for using flakes on this system.
      nix.settings.experimental-features = "nix-command flakes";

      # Enable alternative shell support in nix-darwin.
      programs.zsh.enable = true;
      programs.fish.enable = true;

      # Set Git commit hash for darwin-version.
      system.configurationRevision = self.rev or self.dirtyRev or null;

      # Used for backwards compatibility, please read the changelog before changing.
      # $ darwin-rebuild changelog
      system.stateVersion = 5;

      # The platform the configuration will be used on.
      nixpkgs.hostPlatform = "aarch64-darwin";

      # Set fish as the default shell
      users.users.qys.shell = pkgs.fish;
    };
  in
  {
    # Build darwin flake using:
    # $ darwin-rebuild build --flake .#gloaming
    darwinConfigurations."gloaming" = nix-darwin.lib.darwinSystem {
      modules = [
        configuration
      ];
    };
  };
}

After I logout and login again, the default shell is still /bin/zsh. Manually calling chsh fails, and /etc/shells doesn't seem to be updated:

$ dscl . -read ~/ UserShell                                                   
UserShell: /bin/zsh

$ chsh -s /run/current-system/sw/bin/fish
Changing shell for qys.
Password for qys: 
chsh: /run/current-system/sw/bin/fish: non-standard shell

$ cat /etc/shells 
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/bash
/bin/csh
/bin/dash
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
@Enzime
Copy link
Collaborator

Enzime commented Dec 26, 2024

You'll need to add yourself to users.knownUsers

@nalzok
Copy link
Author

nalzok commented Dec 26, 2024

Ah thanks! I added users.knownUsers = [ "qys" ];, but it gave me an error

darwin-rebuild switch --flake ~/.config/nix-darwin
building the system configuration...
error:
       … while calling the 'derivationStrict' builtin
         at <nix/derivation-internal.nix>:34:12:
           33|
           34|   strict = derivationStrict drvAttrs;
             |            ^
           35|while evaluating derivation 'darwin-system-25.05.20241223.de18642+darwin5.a35b08d'
         whose name attribute is located at /nix/store/73cnf2k7mji95fcflvay15pdw4skhhk5-source/pkgs/stdenv/generic/make-derivation.nix:375:7

       … while evaluating attribute 'activationScript' of derivation 'darwin-system-25.05.20241223.de18642+darwin5.a35b08d'
         at /nix/store/9w5mmnkypiqczdlvmc4l2hd4xc3m44bq-source/modules/system/default.nix:97:7:
           96|
           97|       activationScript = cfg.activationScripts.script.text;
             |       ^
           98|       activationUserScript = cfg.activationScripts.userScript.text;while evaluating the option `system.activationScripts.script.text':

       … while evaluating definitions from `/nix/store/9w5mmnkypiqczdlvmc4l2hd4xc3m44bq-source/modules/system/activation-scripts.nix':

while evaluating the option `system.activationScripts.users.text':

       … while evaluating definitions from `/nix/store/9w5mmnkypiqczdlvmc4l2hd4xc3m44bq-source/modules/users':

while evaluating the option `users.uids':

       … while evaluating definitions from `/nix/store/9w5mmnkypiqczdlvmc4l2hd4xc3m44bq-source/modules/users':

while evaluating the option `users.users.qys.uid':

       (stack trace truncated; use '--show-trace' to show the full, detailed trace)

       error: The option `users.users.qys.uid' was accessed but has no value defined. Try setting the option.

It turns out that I also need to specify my uid. I believe uid should default to 501, so the fact that I have to manually specify uid is probably a (minor) bug?

# Set fish as the default shell
users.knownUsers = [ "qys" ];
users.users.qys.uid = 501;
users.users.qys.shell = pkgs.fish;

In addition, the document for users.knownUsers looks pretty scary. Is this fine?

List of users owned and managed by nix-darwin. Used to indicate what users are safe to create/delete based on the configuration. Don’t add the admin user or other system users to this.

@Enzime
Copy link
Collaborator

Enzime commented Dec 26, 2024

Yeah it's fine, there are safeguards in place, I don't have the time at the moment to update the docs, but if you could open a PR to update it I would review it 👍

@nalzok
Copy link
Author

nalzok commented Dec 26, 2024

Today is literally the first time I tried Nix, so I don't feel confident enough to update the docs right now (e.g., I'm not sure if the default user id is indeed 501, and if so, why I needed to specify it explicitly; I also think it's better to emit a warning instead of silently ignoring the configuration when we cannot "find" the user). Will try to help in the future though!

@Enzime
Copy link
Collaborator

Enzime commented Dec 26, 2024

I agree that we should emit a warning, feel free to open a PR

@nalzok
Copy link
Author

nalzok commented Dec 27, 2024

As a follow up question: how does this work with home-manager? I am confused because there are two programs.fish modules: one by nix-darwin and another by home-manager. It's probably a bad idea to enable both because that would be redundant and may cause inconsistency. Since I want to set fish as the default shell, I have to use the module from nix-darwin. Now, the document of home-manager specifies that

If you do not plan on having Home Manager manage your shell configuration then you must add either

. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"

or

. "/etc/profiles/per-user/$USER/etc/profile.d/hm-session-vars.sh"

to your shell configuration, depending on whether home-manager.useUserPackages is enabled. This file can be sourced directly by POSIX.2-like shells such as Bash or Z shell. Fish users can use utilities such as foreign-env or babelfish.

Since programs.fish.enable = false; in home-manager, now I need to manually put . "/etc/profiles/per-user/$USER/etc/profile.d/hm-session-vars.sh" in ~/.config/fish/config.fish and configure foreign-env or babelfish to do the translation, which seems non-trivial.

In some sense, home-manager works by setting environment variables in these scripts, so it's very important to source them properly. For example, I have programs.neovim = {enable = true; defaultEditor = true; }; in the home-manager configuration. This translates to the following initialization script

$ cat "/etc/profiles/per-user/$USER/etc/profile.d/hm-session-vars.sh"
# Only source this once.
if [ -n "$__HM_SESS_VARS_SOURCED" ]; then return; fi
export __HM_SESS_VARS_SOURCED=1

export EDITOR="nvim"

Without . "/etc/profiles/per-user/$USER/etc/profile.d/hm-session-vars.sh", the default editor would still be nano instead of nvim.

What's the proper way to source the initialization script created by home-manager in the programs.fish module managed by nix-darwin?

@Samasaur1
Copy link
Contributor

I remember for ZSH you need programs.zsh.enable = true; in both nix-darwin and home-manager, so i suspect the same is true for fish

@shusoyo
Copy link

shusoyo commented Dec 30, 2024

What's the proper way to source the initialization script created by home-manager in the programs.fish module managed by nix-darwin?

In my case, I specify a posix shell like bash, zsh, and dash as the login shell (or system layer shell). I also enable the option 'programs.fish.enable' in my nix-darwin config file, By doing so, nix-darwin will generate the enviroment setup scripts in /etc/fish for fish but don't set fish as default shell. Then I enable the 'programs.fish.enable' option in my home-manager, At last, I specific fish as the terminal shell (shell options in kitty.conf).

So I can use fish like a default shell that all nix env sourced when I open a kitty terminal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants