Nix on Non-interactive SSH

I regularly do development via ssh-ing, and while Nix works just fine when I use ssh interactively, it doesn’t seem to get loaded in the path when I just run ssh commands (e.g. ssh nix build). Strangely, I’ve not been able to get it work either with things like ssh 'bash -l -c "nix build"'.

Have anyone got some clues, and what’s the proper way to get it setup?

Try updating your PATH in a file like ~/.envrc, which is always sourced by shells?

In addition to login vs. non-login shells, there’s also interactive vs. non-interactive shells to consider. ssh host will drop you into an interactive login shell. ssh host cmd will do a non-interactive, non-login shell. ‘ssh host /usr/bin/bash -lc “echo hi”’ will give you a non-interactive login shell.

Hm, I do understand that Nix works when I ssh interactively. However, I often would want to use it non-interactively via scripts as well, and non-interactive usage is where my trouble is at.

I recall some threads noting how the Nix /etc/bashrc scripts decide to only place itself in $PATH when the shell is interactive, by checking the presence of the $USER environment variable; I find this behaviour irritating and is the only cli I recall to not be there via non-interactive ssh-ing. And indeed, ssh 'bash -l -c "nix build"' doesn’t work, so I suppose if the intention of the $USER check was to test for interactivity, it seems a bit brittle.

On some systems I’ve manually removed the $USER check, but surely there must be a better way, as I don’t believe I’m the only Nix user who runs scripts via ssh.

Thoughts from anyone else? Much appreciated.

You could move the code where it sources (or however it’s loading nix) to before the check in /etc/bashrc, instead of just deleting the check. This seems tidier than just removing the check.

Another option is to have some kind of exec-with-nix script in your PATH like:

#!/usr/bin/env bash

if [ -e '/nix/var/nix/profiles/default/etc/profile.d/' ]; then
  . '/nix/var/nix/profiles/default/etc/profile.d/'


then ssh <host> exec-with-nix command.

Thank you! Your second option seems quite useful to me; I wonder if I can assume the path /nix/var/nix/profiles/default/etc/profile.d/ to be the constant across different Nix installations (different Nix versions, single-user/multi-user etc).

I don’t know about whether that path could be assumed constant for every system (but would really like to know too).

But some other possibilites that could help with consistency between systems, would be