How to run python under nushell

Following Nushell as default shell I am now trying to run nix-shell python-shell.nix

# shell.nix
let
  # We pin to a specific nixpkgs commit for reproducibility.
  # Last updated: 2024-04-29. Check for new commits at https://status.nixos.org.
  pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/cf8cc1201be8bc71b7cbbbdaf349b22f4f99c7ae.tar.gz") {};
in pkgs.mkShell {
  packages = [
    (pkgs.python3.withPackages (python-pkgs: with python-pkgs; [
      # select Python packages here
      numpy
      matplotlib
      requests
    ]))
  ];
}

and then python which is not found. Any advice?

Works for me, what’s your path?

[nix-shell:~/src/mine/experiment]$ echo $PATH | tr ':' '\n' | grep python
/nix/store/njalkh7rp5jkwz00x6fzpykbajfv1pcz-python3-3.11.9-env/bin


due to

ok, well I guess translate that expression to something nu understands :slight_smile:

or ditch nu when it starts getting too complicated :smirk:

well by my 3 second investigation, $env.PATH should be sufficient to pretty print the path. What do you get if you run that inside the shell?

Even though I don’t think it’s exactly the same, I added nushell to the shell packages and ran

~/src/mine/experiment                                                             43s 19:05:50
❯ nix-shell --run nu
     __  ,
 .--()°'.' Welcome to Nushell,
'|, . ,'   based on the nu language,
 !_-(_\    where all data is structured!

Please join our Discord community at https://discord.gg/NtAbbGn
Our GitHub repository is at https://github.com/nushell/nushell
Our Documentation is located at https://nushell.sh
Tweet us at @nu_shell
Learn how to remove this at: https://nushell.sh/book/configuration.html#remove-welcome-message

It's been this long since Nushell's first commit:
6yrs 5months 9days 1hr 7mins 40secs 651ms 349µs 2ns 

Startup Time: 22ms 247µs 740ns

~/src/mine/experiment> $env.PATH                                        10/19/2025 07:06:55 PM
╭────┬─────────────────────────────────────────────────────────────────────────╮
│  0 │ /nix/store/smkzrg2vvp3lng3hq7v9svfni5mnqjh2-bash-interactive-5.2p37/bin │
│  1 │ /nix/store/z42iz8wl9jb0mhh0nwvxapsqrwv2fc7v-nushell-0.92.1/bin          │
│  2 │ /nix/store/njalkh7rp5jkwz00x6fzpykbajfv1pcz-python3-3.11.9-env/bin      │
│  3 │ /nix/store/ig23ki6sl8dlg3lp0k1l9y9x05wrqs4q-patchelf-0.15.0/bin         │
│  4 │ /nix/store/4kwk49k8rc8cg8c387kbbjcrl8i0y693-gcc-wrapper-13.2.0/bin      │
│  5 │ /nix/store/nn152mgpdfcw92b3b03g9kmnlpd9jris-gcc-13.2.0/bin              │
│  6 │ /nix/store/b93lnii942nnkbpkl6smk8dhv0049di8-glibc-2.39-5-bin/bin        │
│  7 │ /nix/store/asqa3kfq3maclk7cqqhrjvp7vriw6ahy-coreutils-9.5/bin           │
│  8 │ /nix/store/zfs2gv7x073znw6b250rgnbij300hva5-binutils-wrapper-2.41/bin   │
│  9 │ /nix/store/vj57s3h2za2qrfccrvc9b6i7s8mw3ndn-binutils-2.41/bin           │
│ 10 │ /nix/store/asqa3kfq3maclk7cqqhrjvp7vriw6ahy-coreutils-9.5/bin           │
│ 11 │ /nix/store/vf8cjkgwmgd4sb3vkxh6x9iar71s1w1c-findutils-4.9.0/bin         │
│ 12 │ /nix/store/ql4y72l42lrlbk8b4nbfvnc5m0nlp2kk-diffutils-3.10/bin          │
│ 13 │ /nix/store/ard747zf4fkkkqa0pwj3fxp9fhnyfm7p-gnused-4.9/bin              │
│ 14 │ /nix/store/gbrv0fn9a07kmdw2rg22iybdymylw4qc-gnugrep-3.11/bin            │
│ 15 │ /nix/store/1vh7kczjs90fzxd786s7yikvqr1g2ndn-gawk-5.2.2/bin              │
│ 16 │ /nix/store/zs4ajc6bp81c92fj2l5r2d68ra0hmfbb-gnutar-1.35/bin             │
│ 17 │ /nix/store/3fzv6f2c0vxv1zfw8v7baxh4s8qq8r2x-gzip-1.13/bin               │
│ 18 │ /nix/store/1mr1p83pzbcmwqlj7v3cwkq5lbxyszq2-bzip2-1.0.8-bin/bin         │
│ 19 │ /nix/store/fx2yaklnv3h6jx0p07h1bh4vy618pn9s-gnumake-4.4.1/bin           │
│ 20 │ /nix/store/dy2z01kpnxn7dn2kgfdxs4fm8xy9mb89-bash-5.2p26/bin             │
│ 21 │ /nix/store/jmxc8fdl9iwdj5qdg5mq15hz2adbq1yn-patch-2.7.6/bin             │
│ 22 │ /nix/store/v6cqgpxhbcd4bhwvzh22hvy7s2i9j90z-xz-5.4.6-bin/bin            │
│ 23 │ /nix/store/f3ylr5a5w2cla15j2w66n435vwx65xmq-file-5.45/bin               │
│ 24 │ /run/wrappers/bin                                                       │
│ 25 │ /home/ben/.nix-profile/bin                                              │
│ 26 │ /nix/profile/bin                                                        │
│ 27 │ /home/ben/.local/state/nix/profile/bin                                  │
│ 28 │ /etc/profiles/per-user/ben/bin                                          │
│ 29 │ /nix/var/nix/profiles/default/bin                                       │
│ 30 │ /run/current-system/sw/bin                                              │
╰────┴─────────────────────────────────────────────────────────────────────────╯
~/src/mine/experiment> python                                           10/19/2025 07:06:58 PM
Python 3.11.9 (main, Apr  2 2024, 08:25:04) [GCC 13.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 
~/src/mine/experiment>                                                  10/19/2025 07:06:59 PM

which effectively skips bash and just drops me into nushell. $PATH still looks good.

Works for me too, though I use dash as my login shell and hence the default shell for nix-shell doesn’t change. I don’t see how bashInteractive would clear your environment before entering nu just because you’re exec-ing it, though.

Thanks. Still,

nixos: ~ $ cat python-shell.nix
# shell.nix
let
  # We pin to a specific nixpkgs commit for reproducibility.
  # Last updated: 2024-04-29. Check for new commits at https://status.nixos.org.
  pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/cf8cc1201be8bc71b7cbbbdaf349b22f4f99c7ae.tar.gz") {};
in pkgs.mkShell {
  packages = [
    (pkgs.python3.withPackages (python-pkgs: with python-pkgs; [
      # select Python packages here
      numpy
      matplotlib
      requests
    ]))
  ];
}
nixos: ~ $ nix-shell python-shell.nix

results in

nixos: ~ $ $env.PATH
╭───┬───────────────────────────────────────────╮
│ 0 │ /run/wrappers/bin                         │
│ 1 │ /home/someone/.nix-profile/bin             │
│ 2 │ /nix/profile/bin                          │
│ 3 │ /home/someone/.local/state/nix/profile/bin │
│ 4 │ /etc/profiles/per-user/someone/bin         │
│ 5 │ /nix/var/nix/profiles/default/bin         │
│ 6 │ /run/current-system/sw/bin                │
╰───┴───────────────────────────────────────────╯

and python does not run for some reason.

Ok, at this point I guess we need your whole config, or at least the contents of everything bash/nu is sourcing because that’s weird, it’s as if the shell never ran.

You are welcome.

# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).

{ config, pkgs, ... }:

{

  boot.initrd.kernelModules = [ "amdgpu" ];
  hardware.graphics = {
    enable = true;
    enable32Bit = true;
  };

  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
    ];

  # Bootloader.
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

  # Use latest kernel.
  boot.kernelPackages = pkgs.linuxPackages_latest;

  networking.hostName = "nixos"; # Define your hostname.
  # networking.wireless.enable = true;  # Enables wireless support via wpa_supplicant.

  # Configure network proxy if necessary
  # networking.proxy.default = "http://user:password@proxy:port/";
  # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";

  # Enable networking
  networking.networkmanager.enable = true;

  # Set your time zone.
  time.timeZone = "Europe/Berlin";

  # Select internationalisation properties.
  i18n.defaultLocale = "en_US.UTF-8";

  i18n.extraLocaleSettings = {
    LC_ADDRESS = "de_DE.UTF-8";
    LC_IDENTIFICATION = "de_DE.UTF-8";
    LC_MEASUREMENT = "de_DE.UTF-8";
    LC_MONETARY = "de_DE.UTF-8";
    LC_NAME = "de_DE.UTF-8";
    LC_NUMERIC = "de_DE.UTF-8";
    LC_PAPER = "de_DE.UTF-8";
    LC_TELEPHONE = "de_DE.UTF-8";
    LC_TIME = "de_DE.UTF-8";
  };

  # Enable the X11 windowing system.
  services.xserver.enable = true;

  # Enable the GNOME Desktop Environment.
  services.xserver.displayManager.gdm.enable = true;
  services.xserver.desktopManager.gnome.enable = true;

  # Configure keymap in X11
  services.xserver.xkb = {
    layout = "us";
    variant = "";
  };

  # Enable CUPS to print documents.
  services.printing.enable = true;
  hardware.sane.enable = true; # enables support for SANE scanners
  hardware.sane.extraBackends = [ pkgs.hplipWithPlugin ];

  # Enable sound with pipewire.
  services.pulseaudio.enable = false;
  security.rtkit.enable = true;
  services.pipewire = {
    enable = true;
    alsa.enable = true;
    alsa.support32Bit = true;
    pulse.enable = true;
    # If you want to use JACK applications, uncomment this
    #jack.enable = true;

    # use the example session manager (no others are packaged yet so this is enabled by default,
    # no need to redefine it in your config for now)
    #media-session.enable = true;
  };

  # Enable touchpad support (enabled default in most desktopManager).
  # services.xserver.libinput.enable = true;

  # Define a user account. Don't forget to set a password with ‘passwd’.
  users.users.someone = {
    isNormalUser = true;
    description = "Thomas";
    extraGroups = [ "networkmanager" "wheel" "scanner" "lp" ];
    packages = with pkgs; [
    #  thunderbird
    ];
  };

  # Allow unfree packages
  nixpkgs.config.allowUnfree = true;

  # Install firefox.
  programs.firefox.enable = true;

  #############################################################
  # nushell
  programs.bash.interactiveShellInit = ''
    # Some programs launch interactive shells and pretend
    # to use them; such programs always expect a form of POSIX
    # shell.
    #
    # If you don't use programs like that, you can just skip
    # this conditional.
    if ! [ "$TERM" = "dumb" ]; then
      exec nu
    fi
  '';
  # This is the default, just leave it unset, unless you change
  # the default shell for all users for some reason.
  #
  # users.users.username.shell = pkgs.bashInteractive;
  #############################################################

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
   wget
   nushell
   amdgpu_top
   gnome-tweaks
   gnomeExtensions.freon
   gnomeExtensions.appindicator
   gnomeExtensions.tiling-assistant
   google-chrome
   tor-browser
   gedit
   vscodium-fhs
   gnomeExtensions.vscode-workspaces-gnome
   git
   github-desktop

#   ollama
#   (pkgs.ollama.override { 
#      acceleration = "rocm";
#      # acceleration = "cuda";
#    })
#   rocmPackages.rocminfo
#   # clinfo
   
   gparted
   bitwarden
   telegram-desktop
   signal-desktop
   yubikey-personalization-gui
   yubioath-flutter
   gnupg-pkcs11-scd
   shotwell
   xxdiff
   wxmaxima
   stellarium
   evolution
   texlive.combined.scheme-full
   xsane
   ksnip
];

  # Some programs need SUID wrappers, can be configured further or are
  # started in user sessions.
  # programs.mtr.enable = true;
  # programs.gnupg.agent = {
  #   enable = true;
  #   enableSSHSupport = true;
  # };

  # List services that you want to enable:

  # Enable the OpenSSH daemon.
  # services.openssh.enable = true;
  
  services.udev.packages = [ pkgs.yubikey-personalization ];
  programs.gnupg.agent = {
  enable = true;
  enableSSHSupport = true;
  };

  # Open ports in the firewall.
  # networking.firewall.allowedTCPPorts = [ ... ];
  # networking.firewall.allowedUDPPorts = [ ... ];
  # Or disable the firewall altogether.
  # networking.firewall.enable = false;

  # This value determines the NixOS release from which the default
  # settings for stateful data, like file locations and database versions
  # on your system were taken. It‘s perfectly fine and recommended to leave
  # this value at the release version of the first install of this system.
  # Before changing this value read the documentation for this option
  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
  system.stateVersion = "25.05"; # Did you read the comment?

  nix.settings.experimental-features = [ "nix-command" "flakes" ];

  system.autoUpgrade.enable = true;
  system.autoUpgrade.allowReboot = true;

  services.locate.enable = true;
  services.locate.package = pkgs.mlocate;

  services.ollama = {
    enable = true;
    loadModels = [ "gpt-oss"];
    acceleration = "rocm";
    # acceleration = "cuda";
    ##host = "0.0.0.0";
    ##openFirewall = true;
    ##home = "~/.ollama";
    ##models = "~/.ollama/models"; 
  };

nix.gc = {
    automatic = true;
    dates = "daily";
    options = "--delete-older-than 1d";
  };

nix.settings.auto-optimise-store = true;

}

Can you include your ~/.config/nushell/{config.nu,env.nu} and ~/{.bashrc,.bash_login,.bash_profile,.profile} as well? nu might refuse to start if your configuration is broken.

You can also remove the exec from your bash init to maybe get some debug output.

env.nu is empty
config.nu just contains source ($nu.default-config-dir | path join "config-my.nu")
config-my.nu contains

#------------------------
# https://www.nushell.sh/book/aliases.html#replacing-existing-commands-using-aliases
#------------------------
# https://www.nushell.sh/book/aliases.html#replacing-existing-commands-using-aliases
# def template [input1: string, input2: string] {
#     grep --colour=auto -n -i --include $input1 -R $input2 }
#------------------------
# help ...; help aliases; help commands

#------------------------
#def gg [...files: string] {
#    job spawn {
#        ^gedit ...$files | ignore
#    }
#    | ignore
#}
#
#def gg [input?: string] {
#     job spawn { gedit $input } | ignore }

#------------------------
def g [...files: string] {
    job spawn {
        ^gedit ...$files o+e> ~/.gedit.txt
    }
    | ignore
}
alias sg = sudo gedit

def t [...files: string] {
    job spawn {
        ^gnome-text-editor ...$files o+e> ~/.gedit.txt
    }
    | ignore
}
alias st = sudo gnome-text-editor

#------------------------
def d [] { ls }

#def gg [...files: string] {
#    job spawn {
#        ^gedit ...$files | ignore
#    }
#    | ignore
#}

alias dh = ls -alt | head
alias dt = ls -alt
alias lld = ls -al | grep "^d"'
alias lls = ls -al | grep "^l"'
alias dus = ls | sort-by size

# path
#alias ps1 = '\\h: \\W $ '
#alias ps2 = '\\h: \\w $ '
$env.PROMPT_COMMAND = { $'(hostname): ($env.PWD | str replace $nu.home-path ~ | path basename)' }
$env.PROMPT_INDICATOR = ' $ '

#alias l = less -R $*
#alias m = more -R $*

#alias h = history | grep $*
def h [input1: string] {
     history | grep $input1 }
alias hh = history
alias jnow = journalctl -xe -f

#alias xd = xxdiff $1 $2
def xd [input1: string, input2: string] {
     xxdiff $input1 $input2 }

# ollama
alias ol = ollama list
alias or = ollama run gpt-oss-my
alias ora = ollama run gpt-oss-raku
#ollama create gpt-oss-my -f ./Modelfile-my.json
def oc [input1: string, input2: string] {
     ollama create $input1 -f ./($input2) }

#alias ce = sudo cp $* /etc/nixos/configuration.nix
def ce [input1: string] {
     sudo cp $input1 /etc/nixos/configuration.nix }
alias sw = sudo nixos-rebuild switch

#------------------------
# alias gr = grep -H -i -n $1 $2
# ffsf () { grep --colour=auto -n -i --include "$2" -R "$1" }
def gr [input1: string, input2: string] {
    grep --colour=auto -n -i --include $input2 -R $input1 }

# ff() { find . -iname "*$1*" -exec ls -l --color=auto -d {} \; | grep -i "$1" ; }
# ff2() { find . -iname "*$1*" -exec ls -l --color=auto -d {} \; ; }
# ffg () {  echo "ffg \"*.cse\""; ((pattern=$1; shift; find ./ -name "$pattern" -print) | xargs gedit &); }
# ffs () { grep -n -R "$1"; }
# ffsf () { grep -n -i --include "$2" -R "$1"; }
# ffsf () { echo "Omitt * in fn and use '...' for blanks!"; (find ./ -print | grep -i "$2" | xargs grep -i "$1"); }
# ffregex () { find . -type f -regextype egrep -regex '\S*map\S*\/(p20|p63)\_(00[0-9]|0[1-2][0-9])\S*.(res|out)' | sort; }

# perle () { perl -s -E'say sprintf("%.12e",eval $var)' -- -var=$1; }
def perle [input1: string] {
    perl -s -E'say sprintf("%.12e",eval $var)' -- -var=input1; }

#------------------------
# clonedd () { sudo fdisk -l; time sudo dd if=/dev/$1 of=/dev/$2 bs=8M oflag=direct status=progress && sync; }
# backup () { echo "sdd"; sudo fdisk -l; time sudo dd status=progress bs=64K if=/dev/$1 | gzip > ./this.img.gz && sync; }
# restore () { echo "sdd"; sudo fdisk -l; time gunzip -c ./this.img.gz | sudo dd bs=64K of=/dev/$1 status=progress && sync; }
# rs () { echo "SRC-DEST;all directories need a trailing slash (create them before) to allow --delete to be added and to be consistent"; (rsync -uavz $1 $2); }
# alias rl = rsync -uavz 10.0.0.2:/run/media/th6mas/OS/LINUX_DATA/ /run/media/th6mas/96D6F0E9D6F0CB0F/LINUX_DATA
# alias ri = rsync -uavz 10.0.0.2:/run/media/th6mas/OS/Users/Peter/Music/iTunes/ /run/media/th6mas/96D6F0E9D6F0CB0F/Users/Peter/Music/iTunes/

#------------------------
alias r = ssh th6mas@raspberrypi
#alias r = ssh th6mas@raspberrypi;echo "raspberrypi"
#alias ssha = ssh th6mas@192.168.178.42;echo "raspi4-arch"
#alias sshi = ssh indigo@192.168.178.52;echo "ssh indigo@indigosky"
#alias sshv = ssh ssh pi@192.168.178.46;echo "ssh pi@indigosky"

#alias psx = ps auxw --forest

#alias splitfiles = split -b 1800m horizontal_bc_a_trn_coord_002.res 
#alias mergefiles = cat xa* > horizontal_bc_a_trn_coord_002.res
#alias alternativefiles = tar -czvf - <source> | split -b <size> -

#alias perli = rlwrap perl -d -e 1
#alias raki = rlwrap rakudo

#alias stor = cd $HOME/Software/tor-browser;(./start-tor-browser.desktop &);cd
.bashrc
.bash_login
.bash_profile
.profile

do not exist.

Which is my best bet to proceed, if there is no chance to reproduce the issue? Thanks.

Have you attempted this? I still suspect that nu starts and immediately exits for some reason, likely not being able to read a configuration file or such.

Yes, I did but no effect.

I can type exit and it falls back. I suspect, something happens to the PATH.

It has turned out that unfortunately my implementation of the recommended setup, see Nushell as default shell, has not worked. Rather successfully, just run nushell by typing nu from the command prompt and you are good to run python.