Issue
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
Solution
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/ ]]
Answered By - kevinnls Answer Checked By - Candace Johnson (WPSolving Volunteer)