Linux: export environment variable in a shell script to make it flexible on any server - linux

In order to run a Tcl script on Linux, I need to set the environment variable "$LD_LIBRARY_PATH" each time.
For convenience, I develop a shell script to do this.Currently, on my own server, if I type
echo $LD_LIBRARY_PATH
the result is:
/opt/lsf/9.1/linux2.6-glibc2.3-x86_64/lib
so in my shell script I write the following code:
export LD_LIBRARY_PATH="/opt/lsf/9.1/linux2.6-glibc2.3-x86_64/lib:$INSTALL_ROOT/tcl_tk/lib64:$INSTALL_ROOT/tcl_tk/lib64"
where the "$INSTALL_ROOT/tcl_tk/lib64:$INSTALL_ROOT/tcl_tk/lib64" part is what I want to add. It works well. Now the issue is:
If I want to run the script on any server, so the original "$LD_LIBRARY_PATH" will be different, based on my understanding. So how to make it flexible on any server?
I try this in my shell script:
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$INSTALL_ROOT/tcl_tk/lib64:$INSTALL_ROOT/tcl_tk/lib64"
But not so sure,
I am new to system stuffs, need some help. Hope explain the issue clearly.

If your default shell is bash, i would define the variables in ~/.bashrc like:
export INSTALL_ROOT=...##assuming a lready defined
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$INSTALL_ROOT/tcl_tk/lib64:$INSTALL_ROOT/tcl_tk/lib64
So in this way, you dont have to worry anything about setting variables in multiple shell scripts as this .bashrc is going to setup variable for you beforehand.

Related

How to set java environment variables using shell script

I know I can just type
$ vi .bashrc
export JAVA_HOME=/usr/lib/jvm/java-7-oracle
export PATH=$JAVA_HOME/bin:$PATH
However how to use shell script to do it? I prefer to write shell script because I need to configure multiple servers, if type one by one I would take me a long time to go.
Can someone guide me how to do this? Thanks a lot!
EDIT: I just realized that you wanted a script to automate the process of adding environment variables. These commands may work for you:
echo "export JAVA_HOME=/usr/lib/jvm/java-7-oracle" >>~/.bashrc
echo "export PATH=$JAVA_HOME/bin:$PATH" >>~/.bashrc
What this does is append the given text to .bashrc. Instead of copying .bashrc files from server to server, run these commands (you could probably write a script for these) on each server. This preserves the contents of the original rc files on each server, which I find is a better idea than completely overwriting the file.
Original answer
Your .bashrc file is actually written as a shell script. You would place the exact same lines in the shell script, possibly with a hashbang at the beginning of the file. For example:
#!/bin/bash
export JAVA_HOME=/usr/lib/jvm/java-7-oracle
export PATH=$JAVA_HOME/bin:$PATH
# do java stuff here...
If you were to "do java stuff" in this script, this would work fine. However, if these variables are going to be used outside of the script, you would have to "source" this file. That is what happens with .bashrc. Before the first prompt is given, Bash runs source ~/.bashrc to publish the variables defined in .bashrc.

Linux Environment Variables

I'm trying to change my environment variables using a shell script, but the shell script isn't changing it.
Sorry for asking that type of question, but I'm learning about Linux, I just can't figure out what I'm doing wrong here..
Here's the script
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_60
export PATH=$PATH:$JAVA_HOME/bin
export PATH=$PATH:$JAVA_HOME/jre/bin
After I execute this .sh file, when I type
echo $PATH
It doesn't return the new PATH I setted
Instead of executing it like
$ ./script.sh
source it with
$ source script.sh
The first variant creates a new process which does not pass back its modified environment variables to the calling process, while sourcing just executes the script within the already running shell.
See also What is the difference between executing a bash script and sourcing a bash script?
As Andreas explained, you need to source the definition (and you need the export to happen in your current shell process, not in a subshell or child process)
You could instead define in your ~/.bashrc some shell functions to do the job:
## remember the original path at start of the interactive bash
export ORIGINAL_PATH=$PATH
function prepare_for_java() {
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_60
export PATH=$ORIGINAL_PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin
}
function forget_java() {
unset JAVA_HOME
export PATH=$ORIGINALPATH
}
then in your terminal you would type
prepare_for_java
before starting doing Java things, and
forget_java
after you've done with them.
I would suggest to read the Advanced Bash Scripting Guide and Advanced Linux Programming (to get a wider picture).
See also bash(1), credentials(7), fork(2), execve(2), environ(7)

How to make declare in a Linux shell script?

I want to put below declare in a shell script: proxy_set
declare -x https_proxy="https://192.168.220.4:8080/"
And then I execute it like below.
$ ./proxy_set
But "export" shows nothing happened.
And in another way if I execute it like this:
$ source proxy_set
Then "export" shows it works!
My question is how can I make it work without additional "source" cmd?
Thanks!
You can't. Setting variables in the environment only affects the environment of that shell and any future children it spawns; there's no way to affect the parent shell. When you run it without the source (or .), a brand new shell is started up, then the variable is set in that shell's environment, and then that shell exits, taking its environment with it.
The source reads the commands and executes them within the current shell as if you had typed them.
So if you want to set environment variables in a script, you have to source it. Alternatively, you can have a command generate shell commands as output instead of running them, and then the parent can evaluate the output of the command. Things like ssh-agent use this approach.
Try just adding:
export https_proxy="https://192.168.220.4:8080/"
Then execute your script normally.

shell export variable not come into effect

I (on mac osx) often use
export http_proxy=http://192.168.0.205:1099
to proxy http connection to get a highed download speed. To make things easy, I wrote a shell file named proxy.sh to do this:
#!/bin/sh
export http_proxy=http://192.168.0.205:1099
Before I downlaod, I execute proxy.sh shell command, but I found it did't not come into effect.It lost http_proxy variable in current commnad window(terminal). I must type export command in current terminal,it will come into effect.
So I want to know what's reason for this and a solution? thanks.
Running a shell script "normally" (with proxy.sh for example) results in that running in a sub-process so that it cannot affect the environment of the parent process.
Using . or source will run the shell script in the context of the current shell, so it will be able to affect the environment, using one of the following:
. proxy.sh
source proxy.sh
Another possibility (if you're using bash at least) is to create an alias to do the work for you. You can use something like:
alias faster='export http_proxy=http://192.168.0.205:1099'
so that you can then simply type faster on the command line and it will export that variable (in the context of the current shell).
You could also allow for one-shot settings such as:
alias faster='http_proxy=http://192.168.0.205:1099'
and then use:
faster your_program
which would translate into:
http_proxy=http://192.168.0.205:1099 your_program
That's a bash way to set a variable for just the one invocation of a command.
The export variable will only apply to the script -- if you want it to apply to the shell, you need to use source, and execute the script like so:
. ./proxy.sh
or:
source ./proxy.sh
Note the "." in the first example -- the dot follow by space means the script will apply to the shell.
The reason why your script does not work has been explained by Drakosha & how to make your script work has been explained by Anothony. But with the export in the script you need to source your script each time you open a new terminal. A better solution will be to add the export in .bash_profile or .bashrc
Hope this helps!
When executing a shell script a new shell is launched, the script is executed, and the shell dies. That's why you don't see the variable defined in your shell.
I suggest using an alias for the same purpose.

Can a makefile update the calling environment?

Is it possible to update the environment from a makefile? I want to be able to create a target to set the client environment variables for them. Something like this:
AXIS2_HOME ?= /usr/local/axis2-1.4.1
JAVA_HOME ?= /usr/java/latest
CLASSPATH := foo foo
setenv:
export AXIS2_HOME
export JAVA_HOME
export CLASSPATH
So that the client can simply do:
make setenv all
java MainClass
and have it work without them needing to set the classpath for the java execution themselves.
Or am I looking to do this the wrong way and there is a better way?
No, you can't update the environment in the calling process this way. In general, a subprocess cannot modify the environment of the parent process. One notable exception is batch files on Windows, when run from a cmd shell. Based on the example you show, I guess you are not running on Windows though.
Usually, what you're trying to accomplish is done with a shell script that sets up the environment and then invokes your intended process. For example, you might write a go.sh script like this:
!#/bin/sh
AXIS2_HOME=/usr/local/axix2-1.4.1
JAVA_HOME=/usr/java/latest
CLASSPATH=foo foo
export AXIS2_HOME
export JAVA_HOME
export CLASSPATH
java MainClass
Make go.sh executable and now you can run your app as ./go.sh. You can make your script more elaborate too, if you like -- for example, you may want to make "MainClass" a parameter to the script rather than hard coding it.
From your question I am assuming you're using the bash shell.
You can place the variable definitions in a shell script, like so:
AXIS2_HOME=/usr/local/axis2-1.4.1
export AXIS2_HOME
#etc
And then source the script into the current environment, with
source <filename>
or just
. <filename>
That executes the script in the current shell (i.e. no child process), so any environment changes the script makes will persist.
The quick answer is yes, however in your code, you would need to define the variables in the setenv: directive. Doing it at the beginning of the Makefile makes it a local variable to the Makefile. I would use LOCAL_... at the top of the file then set it in the setenv: directive with VAR=LOCAL_VAR etc... Also remember that you will need to call the makefile with make setenv only. I would really look into doing this in a bash script as the variable needs to be created outside of the Makefile. Once the variable has been generated in the environment, you should be able to assign and export from the Makefile.

Resources