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
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/ ]]
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.
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
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 commandconda env list
- which i believe is also the contents of
$ENVS
- which i believe is also the contents of
- hence we can assume you meant
[[ "${ENVS}" == *"RUN_ENV"* ]]
- or alternately
[[ $(conda env list) == *"RUN_ENV"* ]]
- or alternately
- 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/ ]]
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.