How to run passthru script with nix-shell?

Let’s say a derivation provides some script via passthru:
passthru.script1 = ./script1.sh;
How can I run this script with nix-shell?

That will depend on what you are trying to achieve.

  1. For many use cases, the script will be self-contained, so you could just obtain a path to it and execute it directly, without nix-shell.

    How exactly you will do that depends on how is the script defined.

    • If it is a just a path like in your example, or in cacert, you can instantiate the attribute path to get absolute path to run:

      $ nix-instantiate --eval -A cacert.updateScript
      /home/jtojnar/Projects/nixpkgs/pkgs/data/misc/cacert/update.sh
      
    • If it is a derivation, like in gonic, you will want to build it first.

      $ nix-build -A gonic.updateScript
      /nix/store/y7rk79v3smxbpz4r3i5nkg5aicl9wy3y-update-gonic
      
  2. If there are some dependencies, you could run the updated path using nix-shell -p foo -p bar --run "$(nix-instantiate --eval -A cacert.updateScript)".

  3. Though updateScripts specifically have their own launcher so you would use nix-shell maintainers/scripts/update.nix --argstr path cacert rather than executing them directly.

  4. If the script is supposed to modify the environment for the nix-shell, you would have to source it.

    • Directly in bash using something like nix-shell -p curl --run 'bash --init-file <(echo ". \\"$HOME/.bashrc\\"; . \\"$(nix-instantiate --eval -A mypackage.script1)\\"")' (apparently, bash does not offer a nice way to do this)
    • Writing a custom expression for a shell and sourcing the script in shellHook. That is create the following foo.nix file and run nix-shell foo.nix:
      let
        pkgs = import <nixpkgs> { };
      in
      
      pkgs.mkShell {
        buildInputs = [
          pkgs.curl
        ];
        shellHook = ''
          . ${pkgs.mypackage.script1}
        '';
      }
      
2 Likes