【问题标题】:Writing One Shell script to first enter nix shell, then enter the python virtual environment编写One Shell脚本先进入nix shell,再进入python虚拟环境
【发布时间】:2021-02-12 08:24:07
【问题描述】:

我想从 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


    【解决方案1】:

    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 行,因为它们是 cmets。 nix-shell 已经提前设置了正确的环境变量。它继续获取激活文件。

    您可能希望在运行 source 之前生成激活脚本,但我想这取决于您的工作流程。

    或者,您可以使用nix-shell--run COMMAND 选项在 Nix 提供的上下文中运行单个命令。


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

    【讨论】:

    • 您好罗伯特,感谢您的回答。我还是有点迷茫,是不是意味着在#!nix-shell -i bash 行之后,我可以为nix-shell 编写命令?由于我运行了您发布的脚本,并且我没有输入 nix shell 或虚拟环境。根据您的建议,我是否应该生成一个仅包含 source .venv/bin/activate 的脚本?此外,我试图拥有 --run python start.py ,但它显示 line 5: --run: command not found. 我在这里做错了吗?
    • 我理解的方式是你想写一个shell脚本,所以不是交互式的。如果你想在终端中输入一个自动加载 virtualenv 的 Nix shell,你可以编写一个带有 shellHookshell.nix 文件来加载 virtualenv。见nixos.org/manual/nix/stable/#description-13
    • 谢谢。这解决了我们正在寻找的确切问题。
    猜你喜欢
    • 1970-01-01
    • 2013-12-21
    • 2017-02-23
    • 1970-01-01
    • 2019-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多