我经常想在特定的conda环境中启动一个jupyter笔记本。为了加快这一过程,我将这两个命令添加到一个 powershell 脚本中,如下所示:
# conda_notebook.ps1
conda activate my_env
jupyter notebook --ServerApp.root_dir C:\Users\me\my-notebooks
在 anaconda powershell 中执行时效果非常好。 我的 Windows 安装中也有 pyenv-venv 虚拟环境,用于处理 conda 遇到问题的情况,例如 conda 不支持 python 版本(还?)。 方法
# pyenv_notebook.ps1
pyenv-venv activate my_env2
jupyter notebook --ServerApp.root_dir C:\Users\me\my-other-notebooks
不起作用,因为
pyenv-venv activate my_env2
会生成一个新的 shell。因此,第二个参数不会立即执行,而是仅在我 exit
新生成的 shell 时执行。然后,它会失败,因为之前的 shell 中没有 jupyter notebook
命令。 pyenv
套装有一个 pyenv shell
命令,可以更改当前 shell,而不是生成新的 shell。不幸的是,它不存在于pyenv-venv
。
但是,必须有一种方法将第二个命令通过管道传输到第一个命令中,以便第二个命令实际上在新生成的 shell 中执行。我该怎么做?
编辑1:
"jupyter notebook --ServerApp.root_dir D:\drescherlab\misc-win" | pyenv-venv activate dev3.12.3
和
ECHO "jupyter notebook --ServerApp.root_dir D:\drescherlab\misc-win" | pyenv-venv activate dev3.12.3
不工作。我想我们可以预料到这一点,因为
pyenv-venv activate ...
并不期望通过管道传递值。仅当命令 jupyter notebook ...
生成新 shell 后,才必须执行命令 pyenv-venv activate ...
。
我玩了一下,找到了一个潜在的解决方案:
# Execute the activation in a new Process
# BUT: keep input and output bound to the
# current window `-NoNewWindow`
Start-Process -NoNewWindow -FilePath "cmd.exe" -ArgumentList "/c pyenv-venv activate dev3.12.3"
# Wait for start up of new shell
Start-Sleep -Seconds 2
# Use WSH to send keystrokes
# As the newly spawned shell is bound to the
# inputs of this window, the inputs go to
# the newly spawned shell.
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.SendKeys]::SendWait("jupyter notebook --ServerApp.root_dir D:\drescherlab\misc-win{ENTER}")
但是,一旦执行了最后一个命令
[System.Windows...
,脚本就会返回。笔记本的输出仍然显示,但现在输入进入原始 shell 和笔记本。此外,笔记本的输出散布着原始 shell 的 PS C:\Users\me>
输出。
我希望,powershell 能够提供更优雅的解决方案。
如果您希望运行虚拟环境的
cmd.exe
会话保持 开放,请使用 /k
代替 /c
。
要向其传递额外的启动命令,请使用
cmd.exe
的 &
运算符(请注意,如果您想在同一个控制台窗口中执行,则不需要 Start-Process
):
cmd /k 'pyenv-venv activate dev3.12.3 & jupyter notebook --ServerApp.root_dir C:\Users\me\my-other-notebooks'