How to make a system-wise command alias on macOS - java

I want to execute some old code in java, but it's becoming complicated with old versions of it. Therefore, I wanted to create my "Java aliases" so the command "java11" would execute the java 11 binary command. Unfortunately, on mac, I was not successful.
I tried to follow tutorials wanting to add an alias part in your ~/.zshrc. I did that, and it works perfectly, but it doesn't work for bash scripts, which is really annoying.
Here is the line for my java11 alias in the .zshrc:
alias java11="/Library/Java/JavaVirtualMachines/jdk-11.0.11.jdk/Contents/Home/bin/java $#"
(I don't know if it would do anything, but I also added the alias lines in my .bashrc)

Aliases have limited usefulness for things like this. They need to be configured in a shell initialization file (and which file is used depends on the shell, what mode it's started in, etc), they're disabled by default in scripts, and they aren't available at all when the command is executed by something other than a shell (e.g. in sudo java11 ..., it's sudo that does the execution, and it doesn't know anything about aliases).
I'd recommend creating an actual command instead. Since this is just another name for an existing binary (/Library/Java/JavaVirtualMachines/jdk-11.0.11.jdk/Contents/Home/bin/java), you can just use a symbolic link to the original binary (for something more complex, it might make sense to create a wrapper script instead). /usr/local/bin doesn't exist by default in macOS, but it is in the default PATH (in most contexts except cron jobs, grrr), so if you create it, it'll be searched automatically. So something like this should work:
sudo mkdir -p /usr/local/bin
sudo ln -s /Library/Java/JavaVirtualMachines/jdk-11.0.11.jdk/Contents/Home/bin/java /usr/local/bin/java11
In your running zsh sessions, you'll probably have to run rehash to get them to notice the new binary. And remove the alias, to keep it from overriding the new command.

Related

run java exec command, always need full absolute path to the application?

Environment: mac
Precondition: I already configured 'adb' full path to my bash_profile. and when I tried type 'adb' in my terminal, it is working.
But, I tried to exec 'adb' command from java, 'adb' is not working, instead I need to pass the full adb path to make it work.
I guess this is probably something to do with the bash_profile setting, anyone know the exact reason for this issue?
Runtime.getRuntime().exec() runs /bin/sh -c <command>. If this is or points to a bash shell on your system: A non-interactive bash does not read .bash_profile unless explicitly (--login) told to do so.
From the documentation:
When Bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.
It's a little convoluted, but non-interactive, non-login bash instances don't read the profile files.
Your path settings does not get picked up by the subshell (which is actually /bin/sh which might not even be bash at all).
If you want, you can add the path to adb system wide by adding an appropriate entry to to /etc/paths.d.

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.

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

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!

Using Ctags with Gvim on Windows

I'm using gvim as my main 'IDE' on windows 7 and I would like to use ctags to navigate through the code. I've downloaded it and ran based on this tutorial: http://www.techrepublic.com/article/configure-vi-for-java-application-development/5054618
ctags -f ~/.tags -R ~/myprojects/src $JAVA_HOME/src
I've then setup my vimrc with...
set tags=~/.tags
However when I do Ctrl+] on a keyword, it says it can not find the file which the tag is defined in. Shows the correct path except it misses out c:\ from the start so vim can't load it.
How can get it to give me the correct path?
I'm using the latest version of gvim and ctags.
Thanks
FWITW, I'm not entirely sold on the concept of keeping my tags in one location.
This part of the command call:
-f ~/.tags
Nor would I hard path to my current project. This part:
-R ~/myprojects/src
BTW, Windows doesn't have ~ so I don't think either of those would work (not sure if Vim will find ~, i.e. "home").
If I were you, I would cut my teeth on the simplest method until you get more comfortable with the Vim methods and ideals.
Easiest method:
Always let Vim know the "Current Directory" (making the assumption that you are not launching Vim via the command prompt). When you open a file always set the current directory by issuing the following command from normal mode:
:cd %:p:h
Generate a tag file in the current directory with the following command (from normal mode).
:!ctags -R .
Happy jumping.

Call Cygwin from Java app

I need to call Cygwin from Java code ( example : to call make command in Cygwin from Java app which run on linux and windows ).Does anybody have experience with this problem ?
I think you have to differentiate youre code for linux and windows
on linux simply execute the command
on windows lauch your command in cygwin with
C:\cygwin\bin\bash.exe --login -i -c <cmd>
note: you may use apache commons exec to lauch an external command from java
Use ProcessBuilder from Java:
http://download.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html
You will need to make sure your path/environment is set up properly, but that depends on your machine and set up.
Also, note that many cygwin "capabilities" (e.g., less, awk, sed, etc) are simply binaries (executables) that you can call directly -- no need for the bash shell to facilitate access to those. Look at the actual files in wherever your bin folder is (usually c:/cygwin/bin) and try calling those directly from ProcessBuilder. If you need to actually leverage the shell (e.g., pipes, variables, globbing, etc) then that's a different story -- you would then integrate with the bash.exe file itself (check the man page for usage info).

Categories

Resources