无法通过子流程激活Conda环境

时间:2019-12-13 18:36:15

标签: python electron conda

我正在构建一个Electron应用程序(运行Angular应用程序),该应用程序充当下面的python程序的用户界面。

python程序使用anaconda进行程序包管理(我使用miniconda进行开发)。

应用启动时,会检查所需的conda环境是否存在,如果不存在,请创建

以下代码是Service的一部分,它负责管理python程序。

public doEnvironmentSetup() {
    let stdOutSub = new Subject<string>();
    let stdErrSub = new Subject<string>();
    let completeSubject = new Subject<string>();
    this.runningSetup = true;

    const TEMP_ENV_FILE = join(tmpdir(), "env.yml");

    return Promise.resolve()
      .then(() => {

        // Copy packaged environment.yml to TEMP_ENV_FILE

      })
      .then(() => this.electron.getApplicationStoragePath())
      .then((stor) => {

        setTimeout(() => {

          let runProcess = this.electron.childProcess.spawn("conda", ["env", "create", "--file", TEMP_ENV_FILE, "--name", CONDA_ENV_NAME], {
            cwd: stor
          });

          const stdOutReaderInterface = createInterface(runProcess.stdout);
          const stdErrReaderInterface = createInterface(runProcess.stderr);

          stdOutReaderInterface.on('line', (line) => {
            stdOutSub.next(line);
          });

          stdErrReaderInterface.on('line', (line) => {
            stdErrSub.next(line);
          });

          runProcess.on('close', (code: number) => {
            this.electron.fs.unlinkSync(TEMP_ENV_FILE);
            this.runningSetup = false;
            completeSubject.next("");
          });

        }, 2000);

        return {
          stdOut: stdOutSub,
          stdErr: stdErrSub,
          onComplete: completeSubject
        };

      });

  }

现在,当我需要运行实际的python代码时,运行的代码片段是(没有给出全部内容,因为对于我们在此目的而言太长了):

        execCmd.push(
          `conda init ${this.electron.os.platform() === "win32" ? "powershell" : "bash"}`,
          `conda activate ${CONDA_ENV_NAME}`,
          // long python spawn command
          `conda deactivate`,
        )

        setTimeout(() => {

          logLineSubject.next({ out: "--- Setting up Execution Environment ---", err: "" });

          logLineSubject.next({ out: `Running in ${dir}`, err: "" });

          const cmd = execCmd.join(" && ");

          let runProcess = this.electron.childProcess.spawn(cmd, {
            detached: false,
            windowsHide: true,
            cwd: cwd,
            shell: this.getShell()
          });

          const stdOutInterface = createInterface(runProcess.stdout);
          const stdErrInterface = createInterface(runProcess.stderr);

          stdOutInterface.on('line', (line) => {
            // get this line back to the component
          });

          stdErrInterface.on('line', (line) => {
            // get this line back to the component
          });

          runProcess.on("error", (err) => {
            // get this back to the component
          });

          runProcess.on('close', (code: number) => {
            // get this line back to the component
          });

        }, 1000);

其中getShell定义为:

private getShell() {
  return process.env[this.electron.os.platform() === "win32" ? "COMSPEC" : "SHELL"];
}

但是,每当我尝试运行此命令时,它都会返回:

CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
To initialize your shell, run
    $ conda init <SHELL_NAME>
blah blah blah ...

当我尝试使用source activate ${CONDA_ENV_NAME}时,它会返回:

/bin/bash: activate: No such file or directory

不确定我在做什么错。有人可以指出我正确的方向吗?

PS:它可以与source $(conda info --root)/etc/profile.d/conda.sh一起使用,但是由于我也需要支持Windows,所以我不能真正使用它!

免责声明:我是python / anaconda的新手。

3 个答案:

答案 0 :(得分:0)

主要问题是您的外壳(在这种情况下为CMD)未配置为处理conda。您必须通过向PATH环境变量提供Miniconda / Anaconda来将其添加到系统路径。

选中此StackOverflow Question以了解操作方法。

答案 1 :(得分:0)

我不确定要在Windows Powershell中运行什么,但是对于bash,您需要运行likelihoods将bash配置为在启动时运行的脚本,而不是table(is.na(calc_sizes))。也就是说,

conda init

所以应该像

conda init

我怀疑Windows机箱正在运行one of the .bat or .ps1 files in the condabin directory

或者,如果定义了miniconda3/etc/profile.d/conda.sh 并且您拥有Python脚本(例如execCmd.push( `. ${CONDA_ROOT}/etc/profile.d/conda.sh`, `conda activate ${CONDA_ENV_NAME}`, // long python spawn command `conda deactivate`, ) ),那么也许可以使用conda,例如

script.py

,并且可能跨平台工作。但是,conda run太初级,并且缺乏对交互式I / O的支持(它只是缓冲击中stdout / stderr的所有内容,直到进程退出后才返回)。

答案 2 :(得分:0)

更新:

我指的是Windows平台上的&,而且我也通过conda.bat的绝对路径运行conda,而不是调用全局安装的conda。因此用户很容易安装它:

const execPath = path.dirname(process.execPath)
// silent install Miniconda3 to this path (electron-forge resources)
const condaPath = [execPath, "resources", "Miniconda3"].join(path.sep)
const conda = [condaPath, "condabin", "conda.bat"].join(path.sep)
cmd = `${condaPath} activate ${venvPath} & python ${filename} ${arg1} ${arg2}`

我也在寻找这个,而我只是在&那里得到了工作,就像提到的here

我有相同的设置,使用电子和conda进行了与python对话的UI。这是在我的节点中:

spawn(
  `conda activate ${name} & python ${filename} ${arg1} ${arg2}`,
  { shell: true }
);

我也可以流标准输入/输出。确保外壳是正确的。