Nix-direnv and trap not working as expected

Hi all, I am currently trying to setup my dev environments using direnv and nix, so far so good, until I try to setup a cleanup logic using trap (took inspiration from this post trap - Killing background processes started in nix-shell - Unix & Linux Stack Exchange), the script specified after trap gets executed immediately on direnv activation and the shell exit immediately. Maybe something changed in latest releases? Maybe for MacOS is different? I can’t find a solution.

An example flake.nix:

{
  description = "Python 3.12 development environment";
  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
  outputs =
    { self, nixpkgs }:
    let
      system = "aarch64-darwin";
      pkgs = import nixpkgs { inherit system; };
    in
    {
      devShells.${system}.default = pkgs.mkShell {
        buildInputs = [
          pkgs.python312
          pkgs.python312Packages.pip
          pkgs.python312Packages.virtualenv
          pkgs.python312Packages.black
        ];
        shellHook = ''
          VENV=.venv

          if test ! -d $VENV; then
            python3.12 -m venv $VENV
          fi
          source ./$VENV/bin/activate

          if test -f ./requirements.txt; then
            pip install -r requirements.txt
          fi

          trap 'echo "HELLO"' EXIT
        '';
      };
    };
}

The “HELLO” is printed immediately and the dev shell is not activated, while if I remove the trap command everything’s working fine.

I’d have to check, but I suspect the shellHook is run inside a subshell when using direnv, which would explain why the trap fires immediately. That trick likely only works when actually invoking nix-shell.

Yeah what @tejing said is almost certainly the case. I wrote a custom .bashrc in one of my projects to just kill all processes in that env, and that requires me to start the shell manually with a custom bashrc. I’m not at my computer right now so can’t share any details.