-1

In my folder where I keep my other bash scripts, I have created this one:

#! /bin/bash

source $(poetry env info --path)/bin/activate

In a file named poetry_activate. In a bash terminal, the autocomplete works, and when I enter poetry_activate, the virtual environment is not loaded...

However, if I do source $(poetry env info --path)/bin/activate in the terminal, it works. It also works if I do . poetry_activate...

Is there a way to just make the script poetry_activate work?

An old man in the sea.
  • 1,169
  • 1
  • 13
  • 30
  • 2
    Subshells can't affect their parent environments. You have to stick the command into a function and source that function on, e.g., shell startup. – Benjamin W. May 19 '23 at 14:41
  • "source that function" ... in a `.bash_rc` or other similar `.` file so it is automatic. You'll have to figure out which one works best in your use-case. See `man bash` and search for INVOCATION. Good luck. – shellter May 19 '23 at 14:48
  • 1
    Here's the thing -- successfully sourcing configuration into the shell that's running your script only has any effect _for the duration of that script_. So your script is sourcing variables in just fine -- they just disappear when the interpreter they were sourced into exits a moment later. – Charles Duffy May 19 '23 at 14:50

1 Answers1

2

When you execute the script you initiate a subshell; variable assignments made in the subshell are 'lost' when the subshell exits (in this case the poetry_activate script exits).

As you've found, when you source the script (. poetry_activate or source poetry_activate) then no subshell is initiated and instead the commands (within the script) are executed within the current shell.

To eliminate the subshell, while also removing the need to source the script, you could replace the shell script with a function, eg:

poetry_activate() { source $(poetry env info --path)/bin/activate; }

# or

poetry_activate() {
    source $(poetry env info --path)/bin/activate
}

NOTES:

  • in the first example the trailing ; is required to separate the code from the closing }
  • add this to your .profile or .bashrc
  • assumes your PATH has been configured so the OS can find poetry

Now instead of referencing the script you reference the function; an example of referencing the function from the command line:

$ poetry_activate
markp-fuso
  • 28,790
  • 4
  • 16
  • 36
  • by the way, I prefer to `.` a file with that function into my `.bashrc` file. It makes things cleaner, I think ;) – An old man in the sea. May 19 '23 at 14:56
  • 1
    @Anoldmaninthesea. that works, too; I actually have a separate directory with all of my custom functions residing in individual files; my `.profile` then has a loop that sources the individual function definition files; for this answer I didn't want to wander too far off topic hence the direct entry in the `.profile` / `.bashrc` – markp-fuso May 19 '23 at 14:59
  • 1
    ohhhhh that's even better!!! – An old man in the sea. May 19 '23 at 15:01