Episode: 2322 Title: HPR2322: A bit of background on virtualenvwrapper Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr2322/hpr2322.mp3 Transcribed: 2025-10-19 01:19:10 --- This is HPR episode 2,322 entitled a bit on background on Virtuail Rapper. It is posted my first time post-BKB and is about 18 minutes long and currently in a clean flag. The summary is Linux processes, the process environment and the shell as a related to Virtuail Rapper. This episode of HBR is brought to you by an honesthost.com. At 15% discount on all shared hosting with the offer code HBR15, that's HBR15. Better web hosting that's honest and fair at An Honesthost.com. A bit of background on Virtuail Rapper or Linux processes, the process environment and the shell. Hi, I'm BJP, I've been using Linux for, wow, 20 years now. Nox gave a nice podcast on Virtuail Rapper. It was timely for me, I was just trying to use it the other day and not finding all the bits and pieces, so thank you for collecting that info into one place. Nox asked why Virtuail Rapper behaves as it does. Virtuail Rapper is a combination of bash functions and programs. To understand how it works, you need to know a little bit about bash and Linux. I know there have been some very good earlier and current HPR shows on bash, but bash is a huge topic. The main page for it was 3,500 lines about 10 years ago. Now it's 4,300 plus lines. It has a lot of functionality and when you're just trying to get something done, it's overwhelming. So in this HPR episode, I will just answer one or two of Nox's questions. It gives me an excuse to make an episode. Also, I'm not going to go too deep into the description in order to keep the podcast short and to the point. I'm just going to cover what is needed. There is lots more depth. There are several shelves you could use and I'm only going to talk about bash. At startup, bash can read more than just the files I mentioned in this podcast. I'm just not going to cover all the possibilities. That's what the over 4,300 line man pages for. If you have questions, ask them in the comments or make your own podcast and ask them. Maybe you'll get some answers, either from me or from another HPR community member. A program that has no input is not flexible or powerful. As a simple example, a program that displays the results of a hard-coded search is certainly useful if you want to know about that hard-coded search term, but a program that can search for a term that you specify at runtime is so much more useful. You do not have to recompile the program to change the search term. Programs can receive inputs in several ways. On Linux and other Unix-like OSs, a program can be run with arguments, read and write the file descriptors, and that includes standard in, standard out and standard error, and they can receive signals, and they have another input, the environment. That is a bunch of key value pairs that are made available to the program when it starts. Some examples of environment variables are path, home, editor, and pager. The name of the environment variable, for example pager, is the key, and the thing on the other side of the equals sign, like less, is the value. The pair, pager equals less, make up a key value entry in the environment. People who program in C or C++ and maybe other languages know that the program starts with a main function, and that function has some parameters. The first one is account of arguments, and the second one is an array of strings. Each string being one of the arguments passed to the program when it is launched. There is a little known optional third parameter, an array of strings that represents the environment. The way the program gets these strings is edited, it inherits them from its parent process. The parent process of programs that are run from the command line is the command line itself, Bash, or C shell or whatever your shell is. When the program starts, it gets a copy of the exported parts of the environment of its parent. Bash gives you the ability to set these environment variables and to mark them as available for handing to sub-processes, and that is what is happening when you give that export command. You can view all the currently defined variables that have been marked for export by using the N command with no arguments, ENV, echo, November, Victor, or N short for environment. Since these variables are passed down to generations from parent to child, it is usually sufficient to define it once at the top level. The command line itself is a program called Bash, it reads some files at startup. As an example of the generations, you can call Bash from within Bash, and you can call Bash again from within that Bash. Then the first Bash is the parent of the second one, the second one is the parent of the third. The third Bash is the child of the second. You can see the environment changing. Set a variable, Fred equals one in the first shell and export it. Just give the command export, Fred equals one, and don't leave any space around the equal sign, so it's Fred equals one with no spaces. Then run Bash, and in that second Bash, you can run echo, dollar, Fred, and you can see that the value of Fred is one. Now you can change Fred to two with the command export, Fred equals two, and you can run Bash again, and in the third Bash, if you show the value of Fred, you can see that it has inherited the value to echo, dollar, Fred. Now you exit Bash with the exit command, and you're back in the second Bash. If you echo, dollar, Fred, you'll see that Fred is still to, but if you exit Bash again, you get back to the first Bash, and you'll see that Fred is now one. If you echo, dollar, Fred, you'll see the value of one. This is the value from the environment that Bash had before you launched the second Bash. The second and third environments are gone. Those Bash processes have terminated, and their environments were cleaned up and removed when they terminated. You're left with the first environment for the first Bash, and that is an illustration of how that works. In the show notes, there's another example, another exercise, to help with understanding this environment thing. When Bash is a login shell, it reads the .bash profile file from your home directory, kill the slash .bash underscore profile. And it's not a login shell, but some subshell of the login shell. It reads the .bashrc file from your home directory, till the slash .bashrc. So for things that you only need to set once, you can put them in Bash profile. For things that you need to run for each new subshell, you put them in .bashrc. Distributions will set up the user account so that they'll run .bashrc from .bash profile for interactive shells, so that if you need something in all your shells, login, and subshells, you put it in your Bashrc. The path. So the path is one of the environment variables. It is the one that is used by the system to look up the executables. So the system doesn't magically know where the programs are. It looks them up in a predefined series of places, and that predefined series of places is called the path. If you want to run a program, it should be in one of the directories on the path, or you will have to specify the full path to your program when you run it. When you first get your account on a system, there is a default version of the Bashrc and Bash profile files. In Bash profile, there should be a definition of the path. It contains the system directories like slash user slash bin and slash bin. You don't want to remove those from your path, or your shell will become next to useless. You'll have to use full paths for all commands. So the way that people add directories to the path is to assign the existing value of path to itself plus the desired new directory. For example, path equals dollar path colon slash home slash bjb slash bin. It would be me adding my own personal binary directory to the path. But if you put this in Bashrc, then every subshell will have another copy of the directory home bjb bin tacked onto the end of the path. So the right place to put this definition is in Bash profile, where it will be executed once, and then inherited by all the subshells. However, not everything you need in the shell is inherited from the parent program. It turns out that another facility that Bash supplies and that virtual end views is the ability to define and execute Bash functions. Bash also has aliases. A Bash function is a series of Bash commands that have been given a name, and that you can run by typing that name. It can also receive arguments that can influence how the function will behave. HPR Episode 1757 by Dave Morris, called Useful Bash Functions, talks about Bash Functions. You can see the list of currently defined Bash Functions by using the Bash command, declares space minus capital F. That's capital F like Foxtrot. An alias is a simpler version of a function. It is usually just a shorter string to represent a longer, more complicated command, to make command line use easier, assuming you can remember all the aliases in the first place. You can see the list of currently defined aliases by using the Bash command, alias, with no arguments, and it will list out all the currently defined aliases. Virtual end wrapper makes use of Bash Functions. This has consequences. One is that you need to define those functions in every sub-shell. That's why you need to put source user local bin virtual end wrapper.sh in your Bash RC. Well, it seems that on a devian system, virtual end wrapper puts the work on shell function into your shell via a more convoluted route. I will describe it in the show notes. But in the end, the virtual end wrapper file that defines the virtual end wrapper adds the function work on to your shell by sourcing the file, et cetera, BashCompletion.d virtual end wrapper whenever Bash RC is sourced. Note that a single period is shorthand for the Bash Source built-in command. The work on function is defined in et cetera, BashCompletion.d virtual end wrapper. The definition is about the middle of the file. A description of BashCompletion could be a topic of another podcast. I'm not actually volunteering to do this one, just suggesting it as a topic. Another consequence is this. When you run a program, it will inherit a copy of the environment of its parent. When it is done, it will exit, and that environment will disappear. So you cannot run a program or sub-shell to try to affect your environment. It will affect the sub-shell or program environment, and as soon as the command is done, that updated environment will disappear. The source built-in Bash command is meant to allow you to run a bunch of commands in a file as if they had been typed on the command line. So you can put commands that affect the environment, and the environment will still have the changes when the sourcing is done. So virtual end wrapper is mainly changes to the environment. It consists of a few files that are stored in tilde slash dot virtual ends, with names like post-activate and pre-make virtual end. They are basically hooks to add functionality before and after the commands you would issue for virtual end, so you can customize virtual end. To understand virtual end wrapper, let's have a quick look at virtual end first. The things you do with virtual end are to create a virtual end, destroy one, and activate one. So the things you can do with virtual end wrapper are to run some script or scriptlet before or after you create a virtual end, destroy a virtual end, or activate a virtual end. The main thing to customize is the where to find the activate file and the what to do after activating post-activate. It does this by setting environment variables like paths and Python home appropriately, and by defining bash functions to do things like change directory to where the project is. You just have to edit dot virtual ends post-activate to contain the location of your project file. You also define work on underscore home to be the directory that contains all your virtual ends for me that is slash user slash local slash Python ends, but for most people it will be some directory in their home directory. Virtual end manipulates the environment in order to allow you to have different Python setups for your different projects. So to summarize virtual ends manipulates the environment in order to allow you to have different Python setups for your different projects. Handy if you have one project that depends on different versions of Python packages, then another project and you wish to run both. Virtual end leaves a few rough edges, like leaving it up to you to find the virtual end in order to source the activate script. That's where virtual end wrapper comes in. We have talked about the environment and how virtual end wrapper manipulates the environment to make it easier to work with the virtual ends that you have created. The environment refers to the set of environment variables that are defined and passed to child processes. We also discussed the process hierarchy and that a new environment is created for a new process and it is destroyed when that process exits. We covered sourcing a file of shell commands so that if those commands affect the environment, then when the sourcing is done, the environment left is the one that was changed and the changes persist past the source command. We talked about the .bash underscore profile and the .bashrc files and now for the HPR exhortation, you've been listening to hacker public radio. Anyone can make a show. If I can do it, so can you and I look forward to hearing your shows. Thanks, bye bye. You've been listening to Hacker Public Radio at HackerPublicRadio.org. We are a community podcast network that releases shows every weekday Monday through Friday. Today's show, like all our shows, was contributed by an HPR listener like yourself. If you ever thought of recording a podcast, then click on our contributing to find out how easy it really is. HackerPublic Radio was founded by the digital dog pound and the Infonomicon Computer Club and is part of the binary revolution at binrev.com. If you have comments on today's show, please email the host directly, leave a comment on the website or record a follow-up episode yourself. Unless otherwise stated, today's show is released on the Creative Commons, Attribution,