Skip to content
Advertisement

Writing One Shell script to first enter nix shell, then enter the python virtual environment

I want to schedule a job from wsl. The job will need to be run in the nix-shell and then in the python virtual environment under Nix-shell. I try to do this by writing a shell script, run ./enter.sh.

#!/bin/bash
nix-shell -p python38Full python38Packages.virtualenv;
source .venv/bin/activate

However, it doesn’t enter the

(virt)
[nix-shell:xxx] 

after I run ./enter.sh. I need to first run the first line, then run the second line separately. It would be super helpful if someone knows a way to write a shell script that can do these two steps by running one script.

Advertisement

Answer

Shell scripts are a bit different from interactive sessions in the terminal.

When you run nix-shell in your terminal, the original shell process creates a nix-shell process and lets it read your input until nix-shell exits, returning control to the original shell.

In a shell script on the other hand, the shell will read all lines by itself and will not delegate the processing of the shell script to other executables like nix-shell. *

If you want to run all comamnds in the nix-shell, you can use a special shebang at the top of the file. For example:

#!/usr/bin/env nix-shell
#!nix-shell -p python38Full -p python38Packages.virtualenv
#!nix-shell -i bash
source .venv/bin/activate

# insert commands to be run here

/usr/bin/env is just a helper to look up nix-shell without an absolute path. nix-shell is run as a script interpreter that will parse #!nix-shell lines for its own options. The -i bash option tells it to invoke bash as the actual interpreter for this script. bash ignores the shebang and #!nix-shell lines, because they’re comments. nix-shell has set the right environment variables in advance. It continues to source the activate file.

You might want to generate the activate script before running source, but I suppose that depends on your workflow.

Alternatively, you could use the --run COMMAND option of nix-shell to run single commands in the context provided by Nix.


*: commands in parentheses do run in a separate process, but this is mostly an implementation detail. It won’t let other programs take over the execution of the script.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement