2

Can't seem to figure out what the issue is. This is on a Fedora 37 with default setup (bash, gnome, etc...).

What I want to achieve is to create an alias that creates a python virtual environment, where the folder name for the virtual environment is the name of the current working directory (something akin to python3 -m venv $cwd).
This is helpful especially when activating the venv (and later switching directories between project) you can easily identify which venv is enabled.

But for some odd reason this is not working as I expected. To note that I don't have much experience in creating complex aliases but still. I have created the following vars in .bashrc:

  • export cwd="pwd | rev | cut -d '/' -f1 | rev"
    • If I run this in termnial it displays the directory name test as I need it, but when running $cwd in the terminal I get home/<USERNAME>/Projects/VueJS/test
  • export cwd2="${PWD##*/}"
    • This one just displays my username for some reason. I've searched here on stackoverflow and this was one of the suggested methods to get the current directory name

Some indication on how to get started or where to look for info are appreciated. I've tried to search on multiple sources but I can't seem to figure it. I read somewhere that double and single quotes make a difference, but I couldn't understand why and if it would affect this behaviour.

EDIT: To clarify, what I want my alias to run is i.e:

  • python3 -m venv <CURRENT_DIRECTORY_NAME> && source <CURRENT_DIRECTORY_NAME>/bin/activate && [ ! -f ./requirements.txt ] || pip install -r requirements.txt
    • This creates a virtual for python projects
  • python3 -m venv <CURRENT_DIRECTORY_NAME> && source <CURRENT_DIRECTORY_NAME>/bin/activate && pip install nodeenv && nodeenv -p
    • This creates virtual environments for projects that depend on nodejs, which in itself depend on python venv
3
  • Maybe I'm not understanding what you want, but if you want the the current working directory to hold the virtual environment, doesn't python3 -m venv . do the trick? Commented Feb 8, 2023 at 23:59
  • Well the point is not to only run that command, I have a batch of commands that I need to run to setup the dev environment that depends on python venvs.
    – calexandru
    Commented Feb 9, 2023 at 8:31
  • 1
    @ajgringo619 I've edited my post with further clarification
    – calexandru
    Commented Feb 9, 2023 at 8:35

2 Answers 2

1

What is wrong with $cwd?

When you use cwd="pwd | rev | cut -d '/' -f1 | rev" and then $cwd you are actually running pwd with arguments (you do not pipe the output). So basically you are running something like this:

pwd '|' rev '|' cut '-d' "'/'" '-f1' '|' rev

You do not see any error because pwd will ignore non-option arguments. If you use /bin/pwd instead of pwd built-in you can notice the message:

$> /bin/pwd '|'
#Output
/bin/pwd: ignoring non-option arguments

You can test that behavior with this simple script.sh:

#! /usr/bin/env bash

printf "I got: %s\n" "$@"

Make sure you set execution permissions to script.sh

Now change your cwd to:

cwd="./script.sh | rev | cut -d '/' -f1 | rev"

And run $cwd:

(shell)> $cwd
#Output
I got: |
I got: rev
I got: |
I got: cut
I got: -d
I got: '/'
I got: -f1
I got: |
I got: rev

As you can see above the script ./script.sh actually got the values becuase they were passed as arguments so they were not piped.

If you do want to pipe the content stored in the variable $cwd you will have to use eval, like this:

eval $cwd
#Output:
test

I recommend you use functions instead of using strings to run commands (you will avoid these kinds of problems):

getBaseName() { 
   pwd | rev | cut -d '/' -f1 | rev 
}

getBaseName
#Output:
test

Btw, what you are trying to do (print only test) can be achieved by using the command basename:

basename $(pwd)

#Output:
test

Regarding your commands you want to create them an alias. Again, I suggest you use functions (in my opinion alias should be used for short/non-complex commands)

So you can create a function for your two scripts. Also I suggest you use . as a <CURRENT_DIRECTORY_NAME> since using a . will make reference to your current directory. If you pass the output of $cwd this will not make reference to your current path but a directory in your current path which might not exist.

What I meant above is that if you are places under this path:

home/<USERNAME>/Projects/VueJS/test

And you use $cwd for passing the current working directory to the python venv like this: python3 -m venv "$cwd" what you are actually passing is this path home/<USERNAME>/Projects/VueJS/test/$cwd where in your case cwd is test then the real path you are passing is: home/<USERNAME>/Projects/VueJS/test/test.

Solution to your "alias"

createVenv() {
python3 -m venv . && source ./bin/activate && [ ! -f ./requirements.txt ] || pip install -r requirements.txt
}

createVenvNode(){
python3 -m venv . && source ./bin/activate && pip install nodeenv && nodeenv -p
}

Or since you really want to create a venv environment in a new folder (where its name should be the basename of your current directory) then the functions would be:

createVenv() {

# dest="${PWD##*/}"
# You can run the function `getBaseName` and assign its output like this:
dest=$(getBaseName)

if python3 -m venv "$dest" ; then
  cd "$dest"
  source "./bin/activate"
  [ ! -f "./requirements.txt" ] || pip install -r requirements.txt
  echo You are now in new venv environment
else
   echo "Failed to create 'venv' environment" >&2
fi

}

createVenvNode(){

# dest="${PWD##*/}"

# You can run the function `getBaseName` and assign its output like this:
dest=$(getBaseName)

if python3 -m venv "$dest" ; then
   cd "$dest"
   source "./bin/activate"
   # You can test the exit status of these commands with an if statement too
   pip install nodeenv && nodeenv -p
   echo You are now in new venv environment
else
   echo "Failed to create 'venv' environment" >&2
}
13
  • I had this previous setup with "python3 -m venv ." but the problem is that all venv files are dumped in the current folder, and that's not what I want. If I pass a directory name, then this directory will be used for the venv name and all venv related files are inside it. So something like "home/<USERNAME>/Projects/VueJS/test/test" which is what I actually want, because otherwise all venv files are inside "home/<USERNAME>/Projects/VueJS/test/" mixed with my other project folders.
    – calexandru
    Commented Feb 9, 2023 at 11:56
  • Also from other posts, I noted that "basename" is often not used due to it being a 3rd party library and that the folder name could be fetched with regular tools. I don't really mind using it, but if there's a more "natural" of doing it (like I was attempting to) I would prefer that method.
    – calexandru
    Commented Feb 9, 2023 at 11:58
  • @calexandru I've updated the answer (you have to use cd $dest in order to activate and install the dependencies of the new venv enviroment). Regarding: export cwd2="${PWD##*/}". "This one just displays my username for some reason", where are you running that command? Because If you run it in your home directory /home/user then that should be the reason why you get the username. Commented Feb 9, 2023 at 20:28
  • 1
    @calexandru I have no idea what is wrong in your case, however instead of using "${PWD}" use your function, like this: dest=$(getBaseName) (I've updated the answer) Commented Feb 11, 2023 at 0:30
  • 1
    @calexandru oh, many thanks! Actually aliases in my opinion are useful (and I often use them) however when the aliases to use are large commands the best option here is to use functions (or maybe a script) Commented Feb 22, 2023 at 4:37
0

That's not how you do aliases ... try

alias cwd="pwd | rev | cut -d '/' -f1 | rev" 

What's happening with yours is they get evaluated ONCE, when bashrc gets sourced, and your username happens to be the name of your home directory, the last path element when your bashrc was sourced.

1
  • I know how to set an alias (and I forgot to add this), but even setting cwd to an alias it did not work for me. I was still getting the same results.
    – calexandru
    Commented Feb 9, 2023 at 8:30

You must log in to answer this question.

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