can not set linux environment variables as I expect - linux

I open two terminals.
In first terminal:
export CLASSPATH="abc"
printenv CLASSPATH ---> output is abc
then in second terminal:
printenv CLASSPATH ---> no output
why in second terminal I dont have the variable?

It's not going to work because each program inherits environment, that
is a list of environment variables and their values from their parent
process. Environment is not automatically propagated to all other
programs on the system but is only inherited by children of the given
program. To set a global environment that would work in all newly
opened terminals you need set it in the file that is sourced each time
you open the terminal. What file would that be depends on what shell
you use and your system local setup. For example, if you use bash you
should put export CLASSPATH="abc" in ~/.bashrc.

For accessing global variable you need to put $ before it. Are you doing that?
try echo $CLASSPATH
I think you will find this helpful.

Related

Android Studio - cmake - access environement variable?

This question is specific to using cmake as part of Android Studio build process.
I'm using Android Studio 2.2 preview 7 on linux (ubuntu)
Inside the CMakeLists.txt I am able to access the Android NDK path using: ${ANDROID_NDK}
But how can I access:
Any environment variable ?
If not possible, at least the Android SDK path ?
I already tried to used $ENV{name_of_the_environment_variable_here} but it's always empty, even if the environment variable exist. I guess that when gradle invoke cmake it "hide" the env var somehow.
I don't think you can use $ENV, it's just an example of a variable because they're environment variables. However, you should be able to type env and hit enter for a list of the variables you currently have set. Then, the ones you see in the list, you can invoke by typing $VARIABLE_NAME, using a command before them to get them to do something. E.g. echo $VARIABLE will echo your variable to stdout.
I'm not sure how $ANDROID_SDK was set, if it was part of an install process, etc. but generally you would set user environment variables in .profile, .bash_profile or .bashrc configuration files. These files are read by the shell in that order. System-wide variables are set in /etc/environment, /etc/profile, and /etc/bash.bashrc, but you probably don't want to mess with those (most distros encourage making ancillary additions in /etc/profile.local, but that's a story for another answer).
It doesn't particularly matter which one of these files you use, unless what you're trying to do interacts with the order in which they are loaded. Generally, I look for where the variables have been set by either the OS or other stuff I've added and put them near those. You can find where environment variables are set by typing:
% for i in .profile .bash_profile .bashrc; do grep -H PATH $HOME/$i; done
(% is the prompt, don't type %)
.. and this will loop through the 3 files and show you if a user $PATH is set in any of them.
Bash uses the export ENV command as opposed to set ENV, which is from the original sh, which AFAIK is only default on FreeBSD and derivatives like pfSense anymore. Almost all other OS use Bash by default, except MacOS which recently moved to zsh and also uses export, and OpenBSD which uses ksh (nobody uses OpenBSD).
If you want to verify which shell you are using, type echo $SHELL, or echo $0 and hit enter, and it should let you know.
You can add the environment variable ephemerally by typing this command in your bash terminal and pressing enter:
% export ANDROID_SDK_ROOT=/home/username/AndroidSDK
To be clear, this is an example path, so it'd be best to use the actual path in which your android SDK files reside. However, this example was a default install location Android Studio tried to use when I installed it recently, so if you're not sure where they are, it's probably a good place to check.
To have a more permanent setting of your environment variable, open a text editor and add the line above to one of the configuration files I mentioned in the first paragraph (they'll be in your $HOME folder). Or, you can run this from the prompt and it'll add it to your file automatically:
% echo 'export ANDROID_SDK_ROOT=/home/username/AndroidSDK' >> $HOME/.bashrc
Take care to use two angle brackets and not one, as one angle bracket will overwrite the entire file with the single line.
How can I access Any environment variable ?
If you're not sure which folder is $HOME, try typing cd $HOME and hitting enter - that'll take you there. That's how you access environment variables - use a command with the invocation of the variable and it should act as if you had typed out the entire thing.
To access environment variables, type echo $NAME_OF_VARIABLE and it should echo it to the screen. If you want to search your three config files I mentioned in the beginning for where an environment variable is set, you can use grep as I did earlier, just changing the search string for whatever you're looking for. E.g. (while in $HOME):
% grep SDK_ROOT .bashrc .profile .bash_profile
Or you can type env to list all the currently set variables and filter them by piping the output to the grep command:
% env | grep SDK
If you want to just list all of the set variables and root around the entire thing, just type env instead of piping it to grep (grep's a filter).
Lastly, I'll give you an example of my $ANDROID_SDK_ROOT $ANDROID_SDK and $SDK_ROOT variables in my .bashrc - I noticed while installing these tools, they use all three (isn't that fun?):
% grep ANDROID .bashrc
export ANDROID_SDK=$HOME/development/Android/SDK
export ANDROID_SDK_ROOT=$HOME/development/Android/SDK
export PATH=$PATH:$ANDROID_SDK:$JAVA_HOME:$ANDROID_SDK/cmdline-tools/latest/bin:$ANDROID_SDK/build-tools/32.0.0:$ANDROID_SDK/emulator:$ANDROID_SDK/emulator/bin64:$ANDROID_SDK/tools:$ANDROID_SDK/tools/bin:$ANDROID_SDK/extras:$ANDROID_SDK/platform-tools:$HOME/development/AndroidStudio/bin
export ANDROID_STUDIO=$HOME/development/AndroidStudio
% grep SDK_ROOT .bashrc
export SDK_ROOT=$HOME/development/Android/SDK
export ANDROID_SDK_ROOT=$HOME/development/Android/SDK
Hope that answers some questions, sorry it took so long to give you a response.

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.

How to access environment variables inside .gdbinit and inside gdb itself?

I am looking to set up the path for the source code when debugging with gdb. I chose to do that with a .gdbinit file.
Basically, it contains a command:
directory="/path/to/src".
However, I would like to be able to specify that command as:
directory="$SOURCESROOT/src"
where SOURCESROOT is an environment variable. And, if possible, being able to do that inside gdb debuuging session too, by entering directory=$SOURCESROOT/folder.
Basically, I am looking to access inside gdb (or inside .gdbinit) the environment variables.
But not the environment of the debugee (set env and so on), but the environment of the gdb itself (ie. of the bash prompt where I type in the first place "gdb program").
While typing shell $SOURCESROOT inside gdb session shows the content of the environment variable, this is quite useless, as I cannot enter: directory=shell $SOURCESROOT.
PS: Anybody found an ideal setup for Linux (Debian) to download the sources with "apt-get source", to update those with some kind of "apt-get update" utopic command and to install them so that gdb will automatically find these sources?
Nevermind, I found how to do it by using Python scripting.
My .gdbinit file is now:
python
import os
gdb.execute('directory' + os.environ['SOURCES'] + '/package_name/src')
end
show directories
(6 year late!)
Don't use .gdbinit for this purpose. It does not expand env vars. Instead, use this commandline to launch gdb:
gdb --init-eval-command="set dir $SOURCESROOT/src"
(gdb) show dir
/path/to/src
FYI this technique can be used to set other critical variables, e.g
gdb --eval-command="set sysroot $SYSROOTDIR"
Which sets sysroot and solib-absolute-prefix in gdb
If you don't want to involve python, then this could work?
"show environment [varname]
Print the value of environment variable varname to be given to your program when it starts. If you do not supply varname, print the names and values of all environment variables to be given to your program. You can abbreviate environment as env."
ftp://ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_19.html
Maybe they could be used for conditions as well:
https://www.adacore.com/gems/gem-119-gdb-scripting-part-1
In my case I'd like to set global history in common $HOME/.gdbinit, so I used
set history filename ~/.gdb_history
instead of
set history filename $HOME/.gdb_history

How to launch gnome-terminal from command line and duplicate environment variables?

Is there a way to launch a gnome-terminal from the command line (i.e., using the /usr/bin/gnome-terminal command) and have the new terminal inherit the environment variables and other set variables of terminal from which the command was run? The scenario is thus:
Open a terminal
Set some variables
Set some environment variables
Launch an executable that needs the variables and the environment variables of the current terminal in a new terminal
Thoughts?
This turned out to be a gnome-terminal issue. When launching the gnome-terminal, specifying the --disable-factory option provides the following directive:
"Do not register with the activation name server, and do not reuse an already running GNOME terminal process" (gnome-terminal man page)
Specifying this option was required in order to inherit the environment of the previous shell.
You need to use export against the variables in the other shell if you want child processes to inherit them.

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