简体   繁体   中英

Is it possible to activate and execute virtualenv Python from TCL?

This is the bash command that I execute:

  source ./virtualenv/Scripts/activate && cd ./deps/scripts && python generate_system_info.py

Now I want to run this from within a TCL script. I am not sure how this can be achieved.

I know that the exec in TCL is required. However, I am not sure if I can do the activate of virtualenv from TCL using the method shown above. I am also not sure how to integrate the && when I make call to exec inside the TCL shell.

Is what I am trying to achieve even possible?

The TCL shell is from a program called Xilinx Vivado.

The activate script (made from this template by obvious substitutions) sets these environment variables (that you need to care about):

  1. VIRTUAL_ENV — The path of the root of the virtual environment.
  2. PATH — Where binaries are found by... lots of programs! This is extended by the script.
  3. PS1 — The system prompt.

It also removes the PYTHONHOME environment variable (if it was set) and defines a function called deactivate to undo all this.


To do the equivalent in tclsh when running Python as a subprocess, you usually just need to set the first two variables (and do that remove). The clean up happens automatically when Tcl exits. (We omit configuring the prompt; you would only need that if working interactively.)

proc activatePythonVirtualEnvironment {path} {
    global env tcl_platform
    # Allow standard Tcl paths
    set path [file nativename [file normalize $path]]
    set binpath [file nativename [file join [file normalize $path] bin]]
    
    # We can just set this here
    set env(VIRTUAL_ENV) $path

    # Prepend the right form; good thing we have a special global to help
    set env(PATH) $binpath$tcl_platform(pathSeparator)$env(PATH)

    # Eliminate this environment variable if it is set
    unset -nocomplain env(PYTHONHOME)
}

After that, you can exec as normal and things will Just Work™.

activatePythonVirtualEnvironment ./virtualenv/
cd deps/scripts
exec python generate_system_info.py

From the venv documentation:

You don't specifically need to activate an environment; activation just prepends the virtual environment's binary directory to your path, so that “python” invokes the virtual environment's Python interpreter and you can run installed scripts without having to use their full path. However, all scripts installed in a virtual environment should be runnable without activating it, and run with the virtual environment's Python automatically.

So basically activate just replaces path to your python script (and $PATH environment variable, at least in linux). You can just run proper python from virtualenv directory using full/relative path.

If you struggle where it is, you can activate virtualenv and use which command to find it out!

If nothing else, you can execute the whole pipeline like this:

exec bash -c {source ./virtualenv/Scripts/activate && cd ./deps/scripts && python generate_system_info.py}

The && just says "if the previous command succeeded, continue on to the next command". Thus, you could do those three commands on three separate lines. The PROBLEM is that source command. It needs to set environment variables in the current process, and by default tcl would launch a subshell, and when that subshell ended the environment would go away. You CAN set local environment variables in tcl, so maybe the option would be to convert that activate shell script into tcl commands. Then you could do

activate.tcl
cd deps/scripts
exec python generate_system_info.py

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM