Check if conda env exists and create if not in bash

Question:

I have a build script to run a simple python app. I am trying to set it up that it will run for any user that has conda installed and in their PATH. No other prerequisites. I have that pretty much accomplished but would like to make it more efficient for returning users.

build_run.sh

conda init bash
conda env create --name RUN_ENV --file ../run_env.yml -q --force
conda activate RUN_ENV
python run_app.py
conda deactivate

I would like to make it that the script checks if RUN_ENV already exists and activates it instead of forcing its creation every time. I tried

ENVS=$(conda env list | awk '{print }' )
if [[ conda env list = *"RUN_ENV"* ]]; then
   conda activate RUN_ENV
else 
   conda env create --name RUN_ENV --file ../run_env.yml -q
   conda activate RUN_ENV
   exit
fi;
python run_app.py
conda deactivate

but it always came back as false and tried to create RUN_ENV

Asked By: cdub

||

Answers:

update 2022

i’ve been receiving upvotes recently. so i’m going to bump up that this method overall is not natively "conda" and might not be the best approach. like i said originally, i do not use conda. take my advice at your discretion.

rather, please refer to @merv’s comment in the question suggesting the use of the --prefix flag

additionally take a look at the documentation for further details

NOTE: you can always use a function within your bash script for repeated command invocations with very specific flags

e.g

function PREFIXED_CONDA(){
   action=${1};
   # copy $1 to $action;
   shift 1;
   # delete first argument and shift remaining indeces to the left
   conda ${action} --prefix /path/to/project ${@}
}

i am not sure how conda env list works (i don’t use Anaconda); and your current if-tests are vague

but i’m going out on a limb and guessing this is what you’re looking for

#!/usr/bin/env bash
# ...
find_in_conda_env(){
    conda env list | grep "${@}" >/dev/null 2>/dev/null
}

if find_in_conda_env ".*RUN_ENV.*" ; then
   conda activate RUN_ENV
else 
# ...

instead of bringing it out into a separate function, you could also do

# ...
if conda env list | grep ".*RUN_ENV.*" >/dev/null 2>&1; then
# ...

bonus points for neatness and clarity if you use command grouping

# ...
if { conda env list | grep 'RUN_ENV'; } >/dev/null 2>&1; then
# ...

if simply checks the exit code. and grep exits with 0 (success) as long as there’s at least one match of the pattern provided; this evaluates to "true" in the if statement

(grep would match and succeed even if the pattern is just ‘RUN_ENV’ 😉 )


the awk portion of ENVS=$(conda env list | awk '{print }' ) does virtually nothing. i would expect the output to be in tabular format, but {print } does no filtering, i believe you were looking for {print $n} where n is a column number or awk /PATTERN/ {print} where PATTERN is likely RUN_ENV and only lines which have PATTERN are printed.

but even so, storing a table in a string variable is going to be messing. you might want an array.

then coming to your if-condition, it’s plain syntactically wrong.

  • the [[ construct is for comparing values: integer, string, regex
  • but here on the left of = we have a command conda env list
    • which i believe is also the contents of $ENVS
  • hence we can assume you meant [[ "${ENVS}" == *"RUN_ENV"* ]]
    • or alternately [[ $(conda env list) == *"RUN_ENV"* ]]
  • but still, regex matching against a table… not very intuitive imo
  • but it works… sort of
  • the proper clean syntax for regex matching is
    • [[ ${value} =~ /PATTERN/ ]]
Answered By: kevinnls

I made the following script:

if conda info --envs | grep -q base; then echo "base already exists"; else conda create -y -n base; fi

Where base is the name of your env.

Answered By: blevkovych
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.