Unable to set environment variables using source ~/.profile in script - environment-variables

So I have a script, and I'm setting an environment variable using:
echo 'export env_var=hello' >> ~/.profile
source ~/.profile
When the script completes, I check the existence of this environment variable by doing:
echo $env_var
Which gives me "" rather than "hello". If I run source ~/.profile on my terminal (typed straight up in the terminal, not called from any script) , the environment variable will be set correctly. Why is my script unable to set the environment variable correctly, and what do I need to do for it to do so?

env_var is being export-ed all right, but in the subshell (and its children) the script is being executed on.
When you execute an= script, the script is run on a subshell, which is a child of the calling shell, so after the script finishes, the exported variables go out of scope from calling shell's point of view.
A common practice to have all the variables (and other data structures) available in the calling shell, is to source (.) the script, not execute it, which you are doing but from the script, not from the interactive session.

Related

cannot access variable environment from .profile using rails

In my rails application, I exported my database variables in .profile using ansible. the variables are accessible by the command printenv. However, when I run the application or use rails c via ENV['NAME'] , the variables aren't there.
Does anyone have any idea why rails doesn't load variables from .profile?
The ~/.profile script is only meant to be read by your (presumably POSIX compatible) shell. And even then only if it is what is known as a "login" shell. For example, from the bash man page:
When invoked as an interactive login shell, or a non-interactive shell with the --login option, it first attempts to read and execute commands from /etc/profile and ~/.profile, in that order.
If you're running your rails application from an interactive shell prompt it should have access to the env vars you're setting in ~/.profile. If you're starting your rails app some other way (e.g., from your window manager) then you'll need to find some other way to set the env vars that it inherits.

activating conda env vs calling python interpreter from conda env

What exactly is the difference between these two operations?
source activate python3_env && python my_script.py
and
~/anaconda3/envs/python3_env/bin/python my_script.py ?
It appears that activating the environment adds some variables to $PATH, but the second method seems to access all the modules installed in python3_env. Is there anything else going on under the hood?
You are correct, activating the environment adds some directories to the PATH environment variable. In particular, this will allow any binaries or scripts installed in the environment to be run first, instead of the ones in the base environment. For instance, if you have installed IPython into your environment, activating the environment allows you to write
ipython
to start IPython in the environment, rather than
/path/to/env/bin/ipython
In addition, environments may have scripts that add or edit other environment variables that are executed when the environment is activated (see the conda docs). These scripts can make arbitrary changes to the shell environment, including even changing the PYTHONPATH to change where packages are loaded from.
Finally, I wrote a very detailed answer of what exactly is happening in the code over there: Conda: what happens when you activate an environment? That may or may not still be up-to-date though. The relevant part of the answer is:
...the build_activate method adds the prefix to the PATH via the _add_prefix_to_path method. Finally, the build_activate method returns a dictionary of commands that need to be run to "activate" the environment.
And another step deeper... The dictionary returned from the build_activate method gets processed into shell commands by the _yield_commands method, which are passed into the _finalize method. The activate method returns the value from running the _finalize method which returns the name of a temp file. The temp file has the commands required to set all of the appropriate environment variables.
Now, stepping back out, in the activate.main function, the return value of the execute method (i.e., the name of the temp file) is printed to stdout. This temp file name gets stored in the Bash variable ask_conda back in the _conda_activate Bash function, and finally, the temp file is executed by the eval Bash function.
So you can see, depending on the environment, running conda activate python3_env && python my_script.py and ~/anaconda3/envs/python3_env/bin/python my_script.py may give very different results.

Unable to Access ENV variable in rails

I am trying to use env variables in my rails app and set those variable values in ubuntu 14.04
I tried setting using export command
export mongodb_username="abc"
export mongodb_password="cde"
and also tried setting them in /etc/environment and in ~/.bashsrc
and printenv gives following results
>> printenv mongodb_username
=> abc
>> printenv mongodb_password
=> cde
BUT in RAILS APP or irb the output is following
>> ENV['mongodb_password']
=> nil
>> ENV['mongodb_username']
=> nil
I am missing something? Please help!!!
When setting an environment variable's value using export, that value is available only in the shell in which it was set, and its subshells. So you'll need to export those variables in every shell in which you need them.
However, you can automate this, of course.
If you have variables that you need frequently, one approach is to put their assignments in a shell script and then source the shell script in any shells you need them in (see http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x237.html for more on this).
If it's ok to have the variables be in effect in all your shells, then a simpler way is to export them from your startup script (probably ~/.bashrc).

csh script as executable does not setenv

I am not able to set env variables through an executable csh/tcsh script
An env variable set inside a csh/tcsh executable script "myscript"
contents of the script ...
setenv MYVAR /abc/xyz
which is not able to set on the shell and reports "Undefined variable"
I have made the csh/tcsh script as executable by the following shell command
chmod +x /home/xx/bin/myscript
also the path is updated to
set path = (/home/xx/bin $path)
which myscript
/home/xx/bin/myscript
When I run the script on command line and echo the env variable ..
myscript
echo $MYVAR
MYVAR "Undefined variable"
but if i source on command line
source /home/xx/bin/myscript
echo $MYVAR
/abc/xyz
you need to source your code rather than execute it so that it is evaluated by the current shell where you want to modify the environment.
You can of course embed
source /home/xx/bin/myscript
within your .cshrc
the script does not need to be executable or have any #! shebang (though they don't hurt)
This is not how environment variables work.
An environment variable is set for a process (in this case, tcsh) which is passed on to all child processes. So when you do:
$ setenv LS_COLORS=foo
$ ls
You first set LS_COLORS for the tcsh process, tcsh then starts the child process ls which inheres tcsh's environment (including LS_COLORS), which it can then use.
However, what you're doing is setting the environment is a child process, and then want to propagate this back to the parent process (somehow). This is not possible. This has nothing to do with tcsh, it works like this for any process on the system.
It works with source because source reads a file, and executes it line-by-line in the current process. So it doesn't start a new tcsh process.
I will leave it as an exercise to you what the implications would mean if it would be possible :-) Do you really want to deal with unwise shell scripts that set some random environment variables? And what about environment variables set by a php process, do we want those to go back in the parent httpd process? :-)
You didn't really describe what goal you're trying to achieve, but in general, you want to do something like:
#!/bin/csh -f
# ... Do stuff ...
echo "Please copy this line to your environment:"
echo "setenv MYVAR $myvar"

Struggling to unset an environment variable in bash

I have previously set an environment variable using:
echo export "AVARIABLE=example" >> ~/.bash_profile
but now after using:
unset AVARIABLE
the env var remains when I open a new shell? What am I doing wrong here? Even running:
source ~/.bash_profile
does not work?
If you are opening a new shell, about the first thing it does is to source ~/.bash_profile. And there, the variable is set again.
If you want to get rid of it permanently, edit your ~/.bash_profile to remove the line in question again. (This will only take effect for new sessions.)
If you only want to unset it in your current shell, then unset is fine but as you've seen, it won't affect new invocations of the shell.

Resources