2

I'm trying to make a batch script (called run_windows) that check if the python virtual environment exists and if not, create it then activate it, install the requirements and finally run some python code.

set "VIRTUAL_ENV=mat_visualizer_env"

:read_mat
%VIRTUAL_ENV%\Scripts\activate
pip install -r app_files/requirements.txt
python -c "import sys; sys.path.insert(1,'app_files'); from main import visualize_mat_eeg; visualize_mat_eeg('%1')"
pause
EXIT /B 0

IF EXIST "%VIRTUAL_ENV%\Scripts\activate.bat" (
    CALL :read_mat
) ELSE (
    pip install virtualenv
    python -m venv mat_visualizer_env
    CALL :read_mat
)

However, when I run my script, the code exits at line 4: %VIRTUAL_ENV%\Scripts\activate with no errors:

enter image description here

Compo
  • 36,585
  • 5
  • 27
  • 39
Fabio Magarelli
  • 1,031
  • 4
  • 14
  • 47
  • Should it be `%VIRTUAL_ENV%\Scripts\activate.bat`? I believe the `activate` script is a bash script. – RMRiver Aug 30 '22 at 11:26
  • This question is answered almost every week! Please use the search facility in future, ```Call "%VIRTUAL_ENV%\Scripts\activate.bat"```. If you weren't using lazy code, and you understood the `activate` was really a batch file, should know that to run a batch file from another cmd instance, and return to the original instance whilst maintaining its environment, you must use `CALL`. – Compo Aug 30 '22 at 12:19
  • Has been answered every week however adding `.bat` didn't change anything. – Fabio Magarelli Aug 30 '22 at 12:22
  • ```Call``` is the essential part of my comment! _(`.bat` and the doublequotes, are best practice recommendations)_. Did you not read it? or see the word **must**? – Compo Aug 30 '22 at 12:34

2 Answers2

2

Here is a quick example of your batch file rearranged, and using the Call command as previously instructed.

@Echo Off

Set "VIRTUAL_ENV=mat_visualizer_env"

If Not Exist "%VIRTUAL_ENV%\Scripts\activate.bat" (
    pip.exe install virtualenv
    python.exe -m venv %VIRTUAL_ENV%
)

If Not Exist "%VIRTUAL_ENV%\Scripts\activate.bat" Exit /B 1

Call "%VIRTUAL_ENV%\Scripts\activate.bat"
pip.exe install -r app_files/requirements.txt
python.exe -c "import sys; sys.path.insert(1,'app_files'); from main import visualize_mat_eeg; visualize_mat_eeg('%~1')"

Pause
Exit /B 0

Please note, that there is no working directory defined in this script, as was yours, and therefore no way to guarantee that when run, the relative paths point to the intended locations. Additionally, you have not made it clear what %1 was supposed to be, or where it was coming from, so I cannot guarantee whether that is correct.

Compo
  • 36,585
  • 5
  • 27
  • 39
1

Few things:

  • Running the .bat or bash version of activate in is not predictable, Activate.ps1 is found in newer releases. It could probably be used with older versions if copied from a newer release.
  • Scripts in windows (.bat or .cmd in windows) processes from top down, :<ANCHOR> is not skipped like a Sub or Function would be.

I have only worked with the Conda version of activate.ps1 and it adds some nice commands. Had a quick look in standard Python 3.10.5 and it does not add commands but should work fine.

Edit: Added that while working, is not the best option to use the bash version of activate

DaSe
  • 64
  • 5
  • Thank you @DaSe, apologies if this was a question asked every week as suggested by another user. Anyhow, you mentioned the code inside the function is run before actually calling the function as the .bat file is read from top to bottom. Is there a way within the same file, to define and call a function? Thanks. – Fabio Magarelli Aug 30 '22 at 12:36
  • Ps. Using the `ps1` worked perfectly – Fabio Magarelli Aug 30 '22 at 12:38
  • Quick note on :function1 is to make inits first, then a precific call :MainProgram and add your :function1 after the call command. :MainProgram can be further down. - Others are better at answering DOS function GOTO/CALL logic see [stackoverflow.com](https://stackoverflow.com/questions/10149194/something-like-a-function-method-in-batch-files) – DaSe Aug 30 '22 at 12:50