2

I'm trying to create an alias on ZSH.

The aim of the alias is to activate a python virtualenv.

I've put a line in my .zshrc

alias SOU="source /home/andykw/.zshrc && source $(setopt extendedglob &&  ls -d .^git/)/bin/activate"

Often I need to change virtual environment with activating a virtual environment in one of the folder, then switching to another folder and activate another virtual environment.

Example: Let's say I'm working with the folder flask_rest and I have to work on another project, django_rest, I will need to deactivate the flask_rest environment and activate the django_rest environment.

Instead of doing it several times with the command line source <folder_name>/bin/activate then go with another folder source <another_folder_name>/bin/activate, I only need to type SOU.

Hope it makes the context clearer.

PS: I'm using Ubuntu with a Windows Subsystem Linux.

3
  • 1
    Can you explain the objective a bit more clearly? Is the idea that you want to find the single activate file that is in ./*/bin/activate? Can there be more than one? Will you not know the name of the file? Can't you just do source .*/bin/activate?
    – terdon
    Commented Nov 12, 2021 at 15:00
  • Also, what do you mean by only once? If you now want to source a different env, you need to run the command again, isn't that what you want? Are you expecting something that will automatically source the env file every time you move to a new directory?
    – terdon
    Commented Nov 12, 2021 at 15:02
  • @terdon your first comment was spot-on. Thank you.
    – Andy K
    Commented Nov 12, 2021 at 15:10

2 Answers 2

2

Sounds like you want something like:

SOU() {
  set -o localoptions -o extendedglob
  local f
  for f (~/.zshrc ~/.(^git)/bin/activate(N.)) source $f || return
}

For SOU to source your ~/.zshrc and whatever file called bin/activate in hidden directories other than .git in your home directory (ignoring the fact that it doesn't seem to make much sense to me).

You may also want to add the U and r qualifiers to limit to files that you own, and that are readable by the owner.

That defines a function rather than an alias. Aliases are more for csh users. Bourne-like shells have proper programming constructs like functions, though aliases can still be useful there in some corner cases, when you do want it to be handled as text replacements or if the alias needs to do changes in the scope of the caller, none of which seem to be the case here.

You can either put that function definition in your ~/.zshrc or add it as an autoloadable function in one of your $fpath directories. See info zsh autoloading for details.

In any case sourcing ~/.zshrc does not undo what sourcing thosedirs/bin/activate files do. It just redoes whatever is in ~/.zshrc again (which could end up by undoing some of the changes brought by bin/activate but that would be by accident) and if some of those changings are additions, they will end-up accumulating among other problems.

6
  • Hi @Stéphane Chazélas, how do you put it in .zshrc, please?
    – Andy K
    Commented Nov 12, 2021 at 15:22
  • @AndyK, the same way you put your alias line. With a text editor for instance. Commented Nov 12, 2021 at 15:23
  • I've put the function in my zshrc and I cannot activate it...
    – Andy K
    Commented Nov 12, 2021 at 15:38
  • @AndyK, make sure you also remove your SOU alias. What happens when you type SOU or with (){ set -o localoptions -o xtrace; SOU;}? Commented Nov 12, 2021 at 15:55
  • chazélas I've created another function called SOU1 instead of SOU. No error, just one thing that bugged me: When I do a source .zshrc, the charging is stalling.
    – Andy K
    Commented Nov 12, 2021 at 16:04
1

If all you want is an alias that finds the single ./.*/bin/activate file in the current directory tree and sources it, then all you need is:

alias SOU='source. */bin/activate'

If the glob .*/bin/activate matches multiple files, only the first one will be sourced. Your ~/.zshrc file should be sourced every time you open a new non-login interactive shell session, and you probably don't want to be sourcing it multiple times. I suggest you open a new question to try and understand why you seem to need to source it explicitly.

1
  • glob expansion doesn't occur within double quotes. If you remove those doubles quotes, not that if the glob expands to more than one file, the ones after the first one will end up in $1, $2... inside the code in the first. Commented Nov 12, 2021 at 19:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .