3

0

I have to activate the virtual environment (venv) so I running these commands manually in terminal:

source .venv/bin/activate # To activate the virtual env.

and

deactivate # To deactivate the virtual env

This works fine when running manually. Now I have to insert these commands in a bash script to make AWS CodeDeploy to deploy it on a Ubuntu 18.04 server.

My bash script named after_install.sh looks like this...

#!/usr/bin/env bash

set -e
source .venv/bin/activate
## DO SOME STUFF ##
deactivate

For local testing, I made the script executable and ran the script using bash after_install.sh. But nothing happened. It doesn't activate the virtual environment. It seems none of the above commands worked while running the bash script.

I am not getting why these commands work when I run them manually but not with a bash script. What is going on? I need to write these commands inside the bash script so that AWS CodeDeploy can deploy it on the server.

marshmello
  • 33
  • 1
  • 1
  • 3
  • `It doesn't activate the virtual environment` – How exactly do you test this inside the script? My point is: `## DO SOME STUFF ##` obviously does nothing. I don't know `.venv/bin/activate`. Does it output anything when sourced interactively? and doesn't output if sourced in a script? Is this your "test"? – Kamil Maciorowski Apr 30 '20 at 08:50
  • @KamilMaciorowski I mean to say when you run `source .venv/bin/activate` manually it activates your virtual env as it can be seen in the terminal that `.venv` has been activated. But when you use the same command inside the bash script it does not activate `.venv`, seems that the command does not have any effect when running bash script. – marshmello Apr 30 '20 at 09:11
  • Sigh… `as it can be seen in the terminal` – How *exactly*? Do you need the environment in the script? Or outside of the script *after* you "run" it? – Kamil Maciorowski Apr 30 '20 at 09:15
  • @KamilMaciorowski Why do you create a bash script? - To run all things automatically just by executing it so that you do not have run each and every command manually. The same thing I am trying to achieve I have to run this command `source .venv/bin/activate` through a bash script which is not running, as I need the env should get activated after this particular script is executed which is not happening. – marshmello Apr 30 '20 at 09:29
  • There's a difference between expecting something to work in a script and *after* the script. Also note the script contains `deactivate`, so even if you make it affect your current shell, `deactivate` will "win". – Kamil Maciorowski Apr 30 '20 at 09:33
  • @KamilMaciorowski Ok, let's remove `deactivate` and we are only running `source .venv/bin/activate` through bash script. Now accordingly when I execute the bash script do the environment gets activated or not as mentioned in the script? – marshmello Apr 30 '20 at 09:55
  • Have you read my answer to the linked question? You need to source the script (`. after_install.sh` or `source after_install.sh`) to allow commands in the script affect your current shell. For the same reason you need to `source .venv/bin/activate` in the first place (and you do), not just `.venv/bin/activate`. – Kamil Maciorowski Apr 30 '20 at 09:57
  • @KamilMaciorowski I have read your answer to the linked question and I know that I have to source the script, but I do not have to execute/source the script by myself. My role is just to write commands in a script and on my behalf, AWS CodeDeploy will execute it on the server and thats when I do not know how the script will behave. – marshmello Apr 30 '20 at 10:03
  • OK, there is probably an [XY problem](https://meta.stackexchange.com/a/66378/355310) here. I admit I don't fully understand the issue now (I don't know AWS). I'm reopening the question. My advice for you is to [edit] it and state clearly that (1) you want the script to affect something (what?) after the script finishes; (2) and sourcing the script (per [this answer](https://superuser.com/a/1540981/432690)) is not an option. – Kamil Maciorowski Apr 30 '20 at 10:10
  • @marshmello I am guessing you need a specific package in this python env? Can you add a command where you try to load a package that is in this env but NOT in the base env `python -m numpy ... ` or similar. Put this between the activate and deactivate. This should be enough to tell you if the bash works or not – Manish Dash Apr 25 '22 at 23:02

3 Answers3

1

Try to use the full path to virtualenv directory.

#!/usr/bin/env bash

set -e
source /full-path/to/.venv/bin/activate
## DO SOME STUFF -> USE FULL PATH HERE TOO #
deactivate

Best regards.

  • Word of caution: we probably don't want to use `set -e` here since the script is likely to be used with an interactive shell. From the Bash manual, the `set -e` option will "Exit immediately if a pipeline, which may consist of a single simple command, a list, or a compound command *returns a non-zero status.*" The phrase "non-zero status" is UNIX-speak for "error". When "set -e" is enabled and a command fails, *any* command, the shell will exit. This includes tab completion on commands like `python`. https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html#The-Set-Builtin – Lorem Ipsum Jun 02 '22 at 02:50
1

source file_name.sh

worked for me as well (as per Dipanwita Mallick's answer).

The full explanation for why this works is provided here by Lesmana. In summary:

  • Sourcing a script will run the commands in the current shell process. Changes to the environment take effect in the current shell.
  • Executing a script will run the commands in a new shell process.
petrapower
  • 11
  • 1
0

Use source to run the shell script.

source file_name.sh

It worked for me.

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 25 '22 at 21:53