编写一个Shell脚本先进入nix shell,然后进入python虚拟环境

问题描述 投票:0回答:2

我想从 wsl 安排工作。该作业需要在 nix-shell 中运行,然后在 Nix-shell 下的 python 虚拟环境中运行。我尝试通过编写 shell 脚本来做到这一点,运行

./enter.sh

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

但是,它并没有进入

(virt)
[nix-shell:xxx] 

我跑步后

./enter.sh
。我需要先运行第一行,然后单独运行第二行。 如果有人知道一种编写 shell 脚本的方法,该脚本可以通过运行一个脚本来完成这两个步骤,那将会非常有帮助。

python virtualenv windows-subsystem-for-linux nix nixos
2个回答
4
投票

Shell 脚本与终端中的交互式会话有点不同。

当您在终端中运行

nix-shell
时,原始 shell 进程会创建一个
nix-shell
进程并让它读取您的输入,直到
nix-shell
退出,将控制权返回给原始 shell。

另一方面,在 shell 脚本中,shell 将自行读取所有行,并且不会将 shell 脚本的处理委托给其他可执行文件,例如

nix-shell
。 *

如果您想运行

nix-shell
中的所有命令,您可以在文件顶部使用特殊的shebang。例如:

#!/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
只是一个在没有绝对路径的情况下查找
nix-shell
的助手。
nix-shell
作为脚本解释器运行,它将解析
#!nix-shell
行以获取其自己的选项。
-i bash
选项告诉它调用
bash
作为该脚本的实际解释器。
bash
忽略 shebang 和
#!nix-shell
行,因为它们是注释。
nix-shell
已经提前设置了正确的环境变量。它继续获取激活文件。

您可能想在运行之前生成激活脚本

source
,但我想这取决于您的工作流程。

或者,您可以使用

--run COMMAND
nix-shell
选项在 Nix 提供的上下文中运行单个命令。


*:括号中的命令确实在单独的进程中运行,但这主要是一个实现细节。它不会让其他程序接管脚本的执行。


0
投票

今天遇到这个问题,根据评论中的建议查看了 shell.nix 文档的内容,并提出了解决方案。我还发现 NixOS Wiki 也很有帮助(请参阅:https://nixos.wiki/wiki/Development_environment_with_nix-shell)。

单线流量:

  1. 使用
    nix-shell
    自动进入 virtualenv:
# nix-shell looks for shell.nix
nix-shell
# You now using virtualenv
(venv)
[nix-shell:~/example-repo]$ python --version
Python 3.9.16

下面是一个示例

shell.nix
文件:

{ pkgs ? import <nixpkgs> { } }:
pkgs.mkShell {
  # nativeBuildInputs is usually what you want -- tools you need to run
  nativeBuildInputs = with pkgs.buildPackages; [
    python39Full
    python3Packages.virtualenv
  ];
  shellHook = ''
    python39=$(which python3.9)
    virtualenv --python="$python39" ./venv
    source ./venv/bin/activate
  '';
}
© www.soinside.com 2019 - 2024. All rights reserved.