System.getenv doesn't get variables defined in ~/.bash_profile - java

Here is a line in file ~/.bash_profile
export MESSAGE="Hello World"
I want to access system variable MESSAGE in java.
System.getenv("MESSAGE"); doesn't work.

The .bash_profile file is only sourced for login shells. If your java process is spawned from a shell that is not a login shell (for example a script with a #!/bin/sh at the top) then it will not read it (though it may still inherit MESSAGE from the environment depending on how you run it).
Note also that .bash_profile is also not run for interactive shells that are not "login" shells, so you can't rely on it being run even when you have a shell prompt. People usually use .bashrc, which is sourced for all interactive shells, for that purpose.
If you want a variable to be set in all Bourne shell derivatives regardless of whether they are interactive or not, put it in both .profile and .bashrc.

I would recommend you to test if your environment variable is indeed "defined" by using echo $MESSAGE as suggested above.
In addition, changing the bash_profile file will not effect your current shell, you must use "source" in order for it to effect your current shell.
I would also recommend reading this article about differences between bashrc and bash_profile.
Maybe you should define the EXPORT at bashrc?

This actually gets even more interesting for users who have a .profile (for the old Bourne shell), that gets read in by .bash_profile automatically (providing compatability). In either case, the environment variables are read in once only at login shell startup, and all subshells inherit those variables for free. The .bashrc is for tty-dependent things and unheritables like functions (the old sh used $ENV, I think, if it were set, for something similar).
Your use of ~/.bash_profile looks fine (although single quotes are more reliable than double quotes, which allow some substitutions). Make sure you've logged out and back in between editing that file and trying your test, or use ". ~/.bash_profile" (no quotes and note the leading dot and space, since the dot is the command here).
The article at http://www.joshstaiger.org/archives/2005/07/bash_profile_vs.html covers some good things, like using ". ~/.bashrc" at then end of your ~/.bash_profile (excepth that you should use -r, not -f). The comment about using export in your .bashrc is wrong, you should not do this, for two reasons (1) an pretty insignificant performance penalty, (2) a pretty high chance that some command you execute won't get the environment variable - particularly things spawned from your window manager menus and other places where an actual command prompt didn't appear in any of their parents.
Lastly, make sure the $MESSAGE actually exists in your environment - look at the output of the "env" command - if it isn't there, the Java process won't see it unless it's internally creating it and storing it in its own internal copy of the environment variables.
Another note, if you set env variables in the .profile, use this syntax:
VAR=VALUE ; export VAR
...since the old sh shell doesn't support "export VAR=VALUE". Using set -e before a bunch of these and set +e after can remove the need to use "export" at all, if I remember correctly.

Another place to look at: /etc/environment (this may overrule/replace your .bashrc or .bash_profile in shells opened via your IDE)

Variables in your bash profile only get used in the terminal session you are in, so IntelliJ won't pick them up.
Instead, go to Edit Configurations in your Run Configurations box, and add your environment variables in a semi-colon separated list in the environment variables box!

Related

Using Java code to get env variable returns null in MacOS Catalina [duplicate]

What is the proper (2021 way) of creating a permanent environment variable on a Mac (macOS Big Sur) and then use it within a Java project.
There are many very old posts regarding this topic. None of them seem to work properly nowadays.
How to add a permanent environment value (through terminal)?
And how can I use it in a Java code?
I'm also not sure how I was able to add my testvar=testvalue to the list, because I tried so many files (although it seems none of them worked), by adding export testvar=testvalue to the following files:
/etc/paths
~/.bashrc
~/.bash_profile
~/.profile
/etc/profile
Also after inserting it into each file I used source {file}.
So at this point I have no idea which is the proper way to create and have it permanently, and being able to use it in my Java code.
So far, I can print the variables into the terminal like this:
printenv
My variables are getting listed, example:
testvar=testvalue
In my Java code, I get null when using:
System.getenv("testvar")
However using an other variable names that were not created by me, but the macOS system (eg. "USER") prints the value as expected.
macOS Big Sur uses zsh as the default login shell and interactive shell.
If you’re using a Bash profile, such as to set environment variables, aliases, or path variables, you should switch to using a zsh equivalent.
For example:
.zprofile is equivalent to .bash_profile and runs at login, including over SSH
.zshrc is equivalent to .bashrc and runs for each new Terminal session
You can create .zprofile and enter the enter the environment variables there.
Reference
you can edit zprofile using the following command
sudo nano ~/.zprofile
and add your PATH variable.
# Setting PATH for Python 3.9
# The original version is saved in .zprofile.pysave
PATH="/Library/Frameworks/Python.framework/Versions/3.9/bin:${PATH}"
export PATH
to add multiple values to the PATH variable, just add more PATH keys. For example, this is how I added multiple path variables in my M1 mac Monterey
# Setting PATH for Python 3.9
# The original version is saved in .zprofile.pysave
PATH="/Library/Frameworks/Python.framework/Versions/3.9/bin:${PATH}"
PATH="/Users/<name>/.local/bin"
PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
export PATH
This depends on the shell which you are using. For Big Sur, the standard shell is zsh, which might explain why .bashrc and other bash-related configuration files did not work. If you want to set environment variables for your account in zsh, try to create a ~/.zshenv file and put the variable declarations there.
See also: http://zsh.sourceforge.net/Doc/Release/Files.html#Files

Where should i set the environment variable for java in ubuntu? [duplicate]

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
I've used a number of different *nix-based systems of the years, and it seems like every flavor of Bash I use has a different algorithm for deciding which startup scripts to run. For the purposes of tasks like setting up environment variables and aliases and printing startup messages (e.g. MOTDs), which startup script is the appropriate place to do these?
What's the difference between putting things in .bashrc, .bash_profile, and .environment? I've also seen other files such as .login, .bash_login, and .profile; are these ever relevant? What are the differences in which ones get run when logging in physically, logging in remotely via ssh, and opening a new terminal window? Are there any significant differences across platforms (including Mac OS X (and its Terminal.app) and Cygwin Bash)?
The main difference with shell config files is that some are only read by "login" shells (eg. when you login from another host, or login at the text console of a local unix machine). these are the ones called, say, .login or .profile or .zlogin (depending on which shell you're using).
Then you have config files that are read by "interactive" shells (as in, ones connected to a terminal (or pseudo-terminal in the case of, say, a terminal emulator running under a windowing system). these are the ones with names like .bashrc, .tcshrc, .zshrc, etc.
bash complicates this in that .bashrc is only read by a shell that's both interactive and non-login, so you'll find most people end up telling their .bash_profile to also read .bashrc with something like
[[ -r ~/.bashrc ]] && . ~/.bashrc
Other shells behave differently - eg with zsh, .zshrc is always read for an interactive shell, whether it's a login one or not.
The manual page for bash explains the circumstances under which each file is read. Yes, behaviour is generally consistent between machines.
.profile is simply the login script filename originally used by /bin/sh. bash, being generally backwards-compatible with /bin/sh, will read .profile if one exists.
That's simple. It's explained in man bash:
/bin/bash
The bash executable
/etc/profile
The systemwide initialization file, executed for login shells
~/.bash_profile
The personal initialization file, executed for login shells
~/.bashrc
The individual per-interactive-shell startup file
~/.bash_logout
The individual login shell cleanup file, executed when a login shell exits
~/.inputrc
Individual readline initialization file
Login shells are the ones that are read one you login (so, they are not executed when merely starting up xterm, for example). There are other ways to login. For example using an X display manager. Those have other ways to read and export environment variables at login time.
Also read the INVOCATION chapter in the manual. It says "The following paragraphs describe how bash executes its startup files.", i think that's a spot-on :) It explains what an "interactive" shell is too.
Bash does not know about .environment. I suspect that's a file of your distribution, to set environment variables independent of the shell that you drive.
Classically, ~/.profile is used by Bourne Shell, and is probably supported by Bash as a legacy measure. Again, ~/.login and ~/.cshrc were used by C Shell - I'm not sure that Bash uses them at all.
The ~/.bash_profile would be used once, at login. The ~/.bashrc script is read every time a shell is started. This is analogous to /.cshrc for C Shell.
One consequence is that stuff in ~/.bashrc should be as lightweight (minimal) as possible to reduce the overhead when starting a non-login shell.
I believe the ~/.environment file is a compatibility file for Korn Shell.
I found information about .bashrc and .bash_profile here to sum it up:
.bash_profile is executed when you
login. Stuff you put in there might be
your PATH and other important
environment variables.
.bashrc is used for non login shells.
I'm not sure what that means. I know
that RedHat
executes it everytime you start
another shell (su to this user or
simply calling bash again) You might
want to put aliases in there but again
I am not sure what that means. I
simply ignore it myself.
.profile is the equivalent of
.bash_profile for the root. I think
the name is changed to let other
shells (csh, sh, tcsh) use it as well.
(you don't need one as a user)
There is also .bash_logout wich
executes at, yeah good guess...logout.
You might want to stop deamons or even
make a little housekeeping . You can
also add "clear" there if you want to
clear the screen when you log out.
Also there is a complete follow up on each of the configurations files here
These are probably even distro.-dependant, not all distros choose to have each configuraton with them and some have even more. But when they have the same name, they usualy include the same content.
According to Josh Staiger, Mac OS X's Terminal.app actually runs a login shell rather than a non-login shell by default for each new terminal window, calling .bash_profile instead of .bashrc.
He recommends:
Most of the time you don’t want to maintain two separate config files
for login and non-login shells — when you set a PATH, you want it to
apply to both. You can fix this by sourcing .bashrc from your
.bash_profile file, then putting PATH and common settings in .bashrc.
To do this, add the following lines to .bash_profile:
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi
Now when you login to your
machine from a console .bashrc will be called.
A good place to look at is the man page of bash. Here's an online version. Look for "INVOCATION" section.
I have used Debian-family distros which appear to execute .profile, but not .bash_profile,
whereas RHEL derivatives execute .bash_profile before .profile.
It seems to be a mess when you have to set up environment variables to work in any Linux OS.

what are the differences between the various ways to instantiate JAVA_HOME in ubuntu

There are various ways to set the JAVA_HOME variable in ubuntu , simply write the following lines:
JAVA_HOME = / usr/lib/jvm/java-......
export JAVA_HOME
etc ...
but what's the DIFFERENCE if these commands are added:
1] in /etc/profile.d/java.sh
2] in .Profile
Or another way.
If you only want to change the variable in your terminal windows, set it in .bashrc file, which is sourced each time a new terminal is opened. .profile file is not sourced each time you open a new terminal.
See the difference between .profile and .bashrc in question: What's the difference between .bashrc, .bash_profile, and .environment?
The first option will apply to all users.
The second (I suppose you mean $HOME/.profile) applies only to you.
Note that system wide, if you have several JDKs installed with your package manager, you may want to use the update-alternatives command.
Note however that .profile only applies to login shells; you had better put these lines into .bashrc instead.
The first method keeps JAVA_HOME environment variable active only till the time the terminal session is active. If you close the terminal type $JAVA_HOME again it will fail.
The second option adds it to the profile of the user making it like a permanent environment variable which will persist even after a restart.
Let say that, you want to add an environment variable on current terminal like JAVA_HOME, or HTTP_PROXY you can directly set it with export command. When you close terminal, that assignment will be lost. Simply, it is instant assignment for that running operation.
In second option, if you define an entry to .bashrc, it will be available to logged in user that has .bashrc. If you want to set permanent variables for specific user, you can define it in .bashrc in user's home folder.
Additionally, if you put export commant in /etc/environment, it will be available to all users

Setting environment variable permanently from java

Using Java,
How can I add environment variable permanently to the existing env variables.
so that when I do a restart operation for windows or Linux, this environment variable is still there.
You might want to take a look at this.
In Windows you can set a Path Variable from command line so it should do the trick.
I realize this is only applicable to Windows.
Not in any cross platform sort of way. In Linux, these are typically controlled via shell init scripts. You would have to edit one of those (which one depends on the user, system, and shell type). In Windows, this is controlled via system configuration (i'd imagine there are some windows specific APIs to modify those).
coppy the path of jdk upto C:\Program Files\Java\jdk1.6.0\bin from program and past in user variables and put ;.; at the end and give name .
and in system variables click on new and enter the name and past the path....and save ...
go to command prompt
..
to check current paths >echo %path%
to set path >set path="C:\Program Files\Java\jdk1.6.0\bin" enter ok now check and run java program
Environment variables are platform specific. Windows stores them in Registry.
*In the registry the User environment variables are stored at
HKEY_CURRENT_USER\Environment
and the System environment variables are stored at
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment
(from http://demins.blogspot.co.il/2007/10/where-does-windows-xp-store-evrironment.html)*
There are a lot of ways to access windows registry from java. You can for example execute command line using utility named reg that has a reach command line. You can also use one of interoparability APIs like JaWin, Jinterop, Jintegra. You can also refer to my solution explained here.
On linux you can use command line like export MYVAR=myvalue. I mean execute this command line from java using Runtime.exec() or ProcessBuilder. The problem is that this variable will not become really persistent. It will be visiable for all users until the computers is restarted. To make it really persistent you have to modify user login script (e.g. bashrc file for most linux systems if users's default shell is bash).

Script to Change JAVA_HOME System Variable in Windows

I do most of my work against JDK 1.5 - but occasionally I have to change to 1.6. it is a bit painful to have to manually go and change my 'JAVA_HOME' system variable whenever I need to work on a project specific to one or the other (and no, Eclipse doesn't play well in these scenarios - trust me...I've tried.)
I'm looking for a registry script or windows shell script or for that matter any means by which I can "toggle" this system variable with something that is easy to run.
I've messed with the 'set' command, but that only sets the variable for that particular command instance - not globally.
Thanks in advance.
EDIT #1:
Points of advise:
Use the JAVA_HOME variable in your path variable as well, that way you only have to change the JAVA_HOME (which is used in many projects anyways [maven, ant, etc])
Write the command into a couple batch scripts for easy use
When you make the change the windows command session will not reflect it right away. You must close and reopen it.
You could use setx for that purpose
Like so:
setx /M JAVA_HOME "C:\Program Files (x86)\Java\jdk1.6.0_17"

Categories

Resources