Cannot set environmental variable with bash - linux

This is the code I am using:
DBUSER="testing"
DBNAME="testing"
DBPASS="testing"
export SQLALCHEMY_DATABASE_URI=postgresql://{$DBUSER}:{$DBPASS}#localhost/{$DBNAME}
However when I do "printenv" it doesn't list this variable. Can anyone tell me where I went wrong please?

execute your script with . ./yourScript.name or source yourScript.name
EXAMPLE:
cat t
export name=UNIX
./t
echo $name
. ./t
echo $name
UNIX

Environment variables are not global, but per process (and inherited by children).
Variables exported in a script are not available after the script exits.
Instead, you can add the variable to /etc/profile, so that it's read and set by each new login shell. Once added, you have to log out and in again to see it (or source /etc/profile).

Related

incrementing an environmental variable

I need to increment an environmental variable by these steps:
envar=1
export envar
sh script_incrementation
echo $envar
where script_incrementation contains something like this:
#! /bin/sh
envar=$[envar+1] #I've tried also other methods of incrementation
export envar
Whatever I do, after exiting the script the variable remains with its initial value 1.
THanks for your time.
A shell script executes in its own shell, so you cannot affect the outer shell unless you source it. See this question for details of that discussion.
Consider the following script, which I will call Foo.sh.
#!/bin/bash
export HELLO=$(($HELLO+1))
Suppose in the outer shell, I define an environmental variable:
export HELLO=1
If I run the script like this, it run inside its own shell and will not affect the parent.
./Foo.sh
However, if I source it, it will just execute the commands in the current shell, and will achieve the desired affect.
. Foo.sh
echo $HELLO # prints 2
Your script can not change the environment of the calling process (shell), it merely inherits it.
So, if you export foo=bar, and then invoke sh (a new process) with your script, the script will see the value of $foo (which is "bar"), and it will be able to change its own copy of it – but that is not going to affect the environment of the parent process (where you exported the variable).
You can simply source your script in the original shell, i.e. run
source increment_script.sh
or
. increment_script.sh
and that will then change the value of the variable.
This is because sourceing a script avoids spawning a new shell (process).
Another trick is to have your script output the changed environment, and then eval that output, for example:
counter=$[counter+1]
echo "counter=$counter"
and then run that as
eval `increment_script.sh`

How to source file from bash script

I'm trying to source a file with an environment variable from my bash script, but it doesn't work.
This is the content of my script (test.sh), which is located in ~/scripts/test.sh.
#!/bin/bash
FILE_NAME=/tmp/source_file
touch $FILE_NAME
echo "export TEST=\"test\"" > $FILE_NAME
source $FILE_NAME
Then I use alias in my ~/.bashrc.
alias testScript=~/scripts/test.sh
But when I use my script testScript, it didn't set the environment variable.
You need to use:
alias testScript=". ~/scripts/test.sh"
to source the file. Or you can use source in place of ., but I don't much like C shells so I don't use C shell notations such as source.
Environment variables only flow downstream in the process tree.
When you type testScript to a bash process, it creates a child process and execs /bin/bash or whatever is set by #!
Any environment variables set there remain only with the child process. Export causes the variables to be copied to additional grandchildren (children of that child) that might be spawned from that child.
Nothing can copy back to a parent. You need to use source instead of running the file. See Jonathan's answer.
You could try editing the files ~/.bashrc or ~/.login to set enviornment variables you need frequently.
See also https://superuser.com/q/153371 and https://superuser.com/questions/18988/difference-between-a-b-and-export-a-b-in-bash for more explanation of export in bash.
None of the other methods worked for me [source /path/to/file vs . ./path/to/file, alias, etc...], until, thanks to this tutorial I found that using the:
#!/usr/bin/env bash shebang
instead of the simpler #!/usr/bin/env one lets arguments pass on to the interpreter, which I think is the key here – see this document for more info.
In any event, if source commands in any form aren't working for you, try checking your shebang, that might be the problem :)

Export a variable with dynamically created name in bash shell script

I want to create a variable with its name partly dynamic and export it from my bash shell script. I have been trying to do it the following way. No success though. Please tell me where I am wrong.
#!/bin/bash
CURRENT_PROCESS_ID=$$
var=METASTORE_JDBC_DRIVER_$CURRENT_PROCESS_ID
echo $var
export $var='1'
execution command
bash <filename>.sh
I am hoping the script would create an environmental variable like METASTORE_JDBC_DRIVER_8769 and I should be able to use that out of the script but when I do
echo $METASTORE_JDBC_DRIVER_8769 outside the script, doesn't give me anything. Any suggestions/ideas are welcomed.
Bash version 2 introduced the much more intuitive notation ${!var} for dynamically created variable names (a.k.a "indirect referencing")...
a=letter_of_alphabet
letter_of_alphabet=z
echo "a = $a" # Direct reference.
echo "Now a = ${!a}" # Indirect reference. (a = z)
# The ${!variable} notation is more intuitive than the old
#+ eval var1=\$$var2
For details and examples, see http://tldp.org/LDP/abs/html/bashver2.html#EX78
For details and examples using the more well-known eval var1=\$$var2 technique, see http://tldp.org/LDP/abs/html/ivr.html
Export exports variables into the current shell context. By running your script with bash it gets set in that shell's context. You need to source the file to have it run in the current shell context.
source <filename>.sh
Just to show the difference between a sub-shell and source:
[nedwidek#yule ~]# bash test.sh
METASTORE_JDBC_DRIVER_8422
[nedwidek#yule ~]# env |grep META
[nedwidek#yule ~]# source test.sh
METASTORE_JDBC_DRIVER_8143
[nedwidek#yule ~]# env |grep META
METASTORE_JDBC_DRIVER_8143=1

exported variables are not reflected in "env" output

I ran the below script to set environment variables for oracle(oracle_env.sh which comes with oracle package itself).
ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server
export ORACLE_HOME
ORACLE_SID=XE
export ORACLE_SID
NLS_LANG=`$ORACLE_HOME/bin/nls_lang.sh`
export NLS_LANG
PATH=$ORACLE_HOME/bin:$PATH
export PATH
if [ $?LD_LIBRARY_PATH ]
then
LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
else
LD_LIBRARY_PATH=$ORACLE_HOME/lib
fi
export LD_LIBRARY_PATH
After that when I ran env to ensure that the variables are exported properly, I found no properties are exported(below is the output).
invincible:/home/invincible# /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/oracle_env.sh
invincible:/home/invincible# env | grep ORACLE_HOME
invincible:/home/invincible#
Now I am not sure whether variables are exported properly.If not what I have done wrong? Please help me out.
And one more thing, I am running as root.
The scripts only sets the environment inside the subshell it runs in. You should source it:
# POSIX
. /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/oracle_env.sh
or
# bash/ksh
source /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/oracle_env.sh
I believe that when you run a script, bash forks and execs the script in a new shell instance, any exports done in the script doesn't propagate back to your parent shell.
However it seems that you can simply execute your script with:
prompt$ . /path/to/script.sh # note the period!
Example:
prompt$ echo "export FOO=foobar" > /tmp/tst
prompt$ sh /tmp/tst
prompt$ echo $FOO
prompt$ . /tmp/tst
prompt$ echo $FOO
foobar
I believe you should use source to load that script.
source /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/oracle_env.sh
From man source:
source filename [arguments]
Read and execute commands from filename in the current shell environment and
return the exit
status of the last command executed from filename.
Exporting variables only makes them available to children of the shell you export them from. There is no way of changing the environment variables in the parent shell, as you seem to be trying to do. You can change the variables in the same shell by sourcing the script using the "dot" command:
. myscript

How to export a variable in Bash

I need to set a system environment variable from a Bash script that would be available outside of the current scope. So you would normally export environment variables like this:
export MY_VAR=/opt/my_var
But I need the environment variable to be available at a system level though. Is this possible?
Not really - once you're running in a subprocess you can't affect your parent.
There two possibilities:
Source the script rather than run it (see source .):
source {script}
Have the script output the export commands, and eval that:
eval `bash {script}`
Or:
eval "$(bash script.sh)"
This is the only way I know to do what you want:
In foo.sh, you have:
#!/bin/bash
echo MYVAR=abc123
And when you want to get the value of the variable, you have to do the following:
$ eval "$(foo.sh)" # assuming foo.sh is in your $PATH
$ echo $MYVAR #==> abc123
Depending on what you want to do, and how you want to do it, Douglas Leeder's suggestion about using source could be used, but it will source the whole file, functions and all. Using eval, only the stuff that gets echoed will be evaluated.
Set the variable in file /etc/profile (create the file if needed). That will essentially make the variable available to every Bash process.
When i am working under the root account and wish for example to open an X executable under a normal users running X.
I need to set DISPLAY environment variable with...
env -i DISPLAY=:0 prog_that_need_xwindows arg1 arg2
You may want to use source instead of running the executable directly:
# Executable : exec.sh
export var="test"
invar="inside variable"
source exec.sh
echo $var # test
echo $invar # inside variable
This will run the file but in same shell as the parent shell.
Possible downside in some rare cases : all variables regardless of explicit export or not will be exported. If some variables are required to be unset, unset those explicitly. Similarly, handle imported variables.
# Executable : exec.sh
export var="test"
invar="inside variable"
# --- #
unset invar

Resources