`su` does not work inside `system.activationScripts`, `nixos-enter` can't run any command

While trying to solve the problem I listed in this, this and this topics I came up with a small activation script:

system.activationScripts.setup.text =
# Check if it's the first time the script ran
if [ -e /etc/nixos/.setup-done ]
then exit
  # Variables

  # Create folder structure
  mkdir -p /home/andy3153/src
  cd /home/andy3153/src

  mkdir -p hyprland/hyprland-rice
  mkdir -p nixos/nixos-rice
  mkdir -p nvim/andy3153-init.lua
  mkdir -p sh/andy3153-zshrc

  # Clone Git repos
  $git clone $ghlink/hyprland-rice hyprland/hyprland-rice
  $git clone $ghlink/nixos-rice nixos/nixos-rice
  $git clone $ghlink/andy3153-init.lua nvim/andy3153-init.lua
  $git clone $ghlink/andy3153-zshrc sh/andy3153-zshrc

  # Link NixOS configs in their place
  rm -r /etc/nixos
  ln -s /home/andy3153/src/nixos/nixos-rice/etc/nixos /etc/

  # Link home-manager configs in their place
  rm -r /home/andy3153/.config/home-manager
  ln -s /home/andy3153/src/nixos/nixos-rice/home/andy3153/.config/home-manager/ ~andy3153/.config/

  # Install Home Manager for andy3153
  $su andy3153 -c "\
  nix-channel --add https://github.com/nix-community/home-manager/archive/release-23.05.tar.gz home-manager\
  nix-channel --update\
  nix-shell \<home-manager\> -A install\

  # Make sure andy3153 owns his files
  chown -R andy3153:andy3153 /home/andy3153

  # Ensure it's the last time the script runs
  touch /etc/nixos/.setup-done

See the entire configuration.nix here.

Upon running nixos-install, it tries running su but fails, complaining that it can’t run zsh (user andy3153’s default shell). Seeing this keeps repeating itself over and over, even if I change the shell, I decided to chroot into the system.

So I used nixos-enter, which popped me into the environment of the installed system, but with a pretty large problem. The only commands that were able to run were shell builtins.

Getting out of the live installer and actually booting into the system shows everything works normally, but the nixos-install command did not run my su command to install home-manager for my user, so I consider it incomplete.

I don’t know what to do to fix this issue, can anyone help?

How do you change the shell? Can you set it to ${pkgs.runtimeShell} with the --shell flag so it’s an absolute path into the nix store?

All I was doing is instead of using

${pkgs.su}/bin/su andy3153 -c "..."

I tried

${pkgs.su}/bin/su andy3153 -c ${pkgs.bash}/bin/bash -c "..."


${pkgs.su}/bin/su andy3153 -c ${pkgs.zsh}/bin/zsh -c "..."


${pkgs.su}/bin/su andy3153 -c ${pkgs.sh}/bin/sh -c "..."

etc. You get the point

How’d I do that?

That’s not how su works. I’m not even sure if multiple -c do anything, they likely override each other? The man page isn’t clear about this.

Changing the shell with su is done with the -s or --shell flag:

${pkgs.su}/bin/su andy3153 --shell ${pkgs.runtimeShell} --command "..."

That solves this issue. But, now I’ve got another issue. su now runs as intended, but when it tries running nix-channel, it gives this error:

error: could not set permissions on '/nix/var/nix/profiles/per-user' to 755: Operation not permitted

What to do about it? By the way, the latest version of the activation script now looks like this. I fixed some obvious problems with it.