Modifying $PATH variable by a bash alias - bash

I created this alias in my .bashrc file:
alias changepath="export PATH=$JAVA_HOME/bin:$PATH"
What I want to do is change $JAVA_HOME and then change the $PATH to include the new $JAVA_HOME/bin.
When I change $JAVA_HOME and type this command instead of using the alias, it works as expected.
However, when I change $JAVA_HOME and then use the alias, the changepath command prepends the old $JAVA_HOME/bin instead of the new $JAVA_HOME/bin to $PATH.
How can I fix this?

You can also defer evaluation of variables by single-quoting your alias definition, i.e.
alias changepath='export PATH=$JAVA_HOME/bin:$PATH'
Note that the alias or function solutions do not solve the problem of clearing any previous JAVA_HOME you have set.
So you can wind up with a crazy PATH
PATH="/usr/bin:/sys"
PATH=/usr/bin/java:/usr/bin:/sys
PATH=/usr/bin/java/bin:/usr/bin/java:/usr/bin:/sys

Try to use a function instead:
changepath () {
export PATH="$JAVA_HOME/bin:$PATH";
}
In your case "$JAVA_HOME and $PATH are interpreted when you set the alias. So they are fixed to the moment when you execute the .bashrc.
With a function, variables will be interpreted at launching.
Note: I copy/paste you export PATH=..., but be careful you will add $PATH's content at every launch.

This is how I approached the problem of changing between Java 7 and 8 SDKs. I am sure someone could improve these bash functions but I guess the important part is using sed to edit the path.
This will find and replace the JAVA_HOME value rather than keep adding to the PATH variable.
function java7 () {
export PATH=$(echo $PATH | sed s~$JAVA_HOME~${JAVA_7_HOME}"/bin"~)
export JAVA_HOME="${JAVA_7_HOME}";
}
function java8 () {
export PATH=$(echo $PATH | sed s~$JAVA_HOME~${JAVA_8_HOME}"/bin"~)
export JAVA_HOME="${JAVA_8_HOME}";
}

I need to switch between 8 and 11 so what I did was:
Add NO_JAVA_PATH in .profile
export NO_JAVA_PATH=$PATH
export JAVA_HOME="<path>"
export PATH=$JAVA_HOME/bin:$PATH
Added aliases in .bashrc
alias j8='export JAVA_HOME="<path>" ; export PATH=$JAVA_HOME/bin:$NO_JAVA_PATH'
alias j11='export JAVA_HOME="<path>" ; export PATH=$JAVA_HOME/bin:$NO_JAVA_PATH'

Related

zsh: command not found: symfony on ubuntu 20 [duplicate]

I'm using zsh terminal, and I'm trying to add a new entry (/home/david/pear/bin) to the PATH variable. I don't see a reference to the PATH variable in my ~/.zshrc file, but doing echo $PATH returns:
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
So I know that the path variable is being set somewhere. Where is the PATH variable set / modified for the zsh terminal?
Actually, using ZSH allows you to use special mapping of environment variables. So you can simply do:
# append
path+=('/home/david/pear/bin')
# or prepend
path=('/home/david/pear/bin' $path)
# export to sub-processes (make it inherited by child processes)
export PATH
For me that's a very neat feature which can be propagated to other variables.
Example:
typeset -T LD_LIBRARY_PATH ld_library_path :
Here, add this line to .zshrc:
export PATH=/home/david/pear/bin:$PATH
EDIT: This does work, but ony's answer above is better, as it takes advantage of the structured interface ZSH provides for variables like $PATH. This approach is standard for bash, but as far as I know, there is no reason to use it when ZSH provides better alternatives.
You can append to your PATH in a minimal fashion. No need for
parentheses unless you're appending more than one element. It also
usually doesn't need quotes. So the simple, short way to append is:
path+=/some/new/bin/dir
This lower-case syntax is using path as an array, yet also
affects its upper-case partner equivalent, PATH (to which it is
"bound" via typeset).
(Notice that no : is needed/wanted as a separator.)
Common interactive usage
Then the common pattern for testing a new script/executable becomes:
path+=$PWD/.
# or
path+=$PWD/bin
Common config usage
You can sprinkle path settings around your .zshrc (as above) and it will naturally lead to the earlier listed settings taking precedence (though you may occasionally still want to use the "prepend" form path=(/some/new/bin/dir $path)).
Related tidbits
Treating path this way (as an array) also means: no need to do a
rehash to get the newly pathed commands to be found.
Also take a look at vared path as a dynamic way to edit path
(and other things).
You may only be interested in path for this question, but since
we're talking about exports and arrays, note that
arrays generally cannot be exported.
You can even prevent PATH from taking on duplicate entries
(refer to
this
and this):
typeset -U path
PATH pre-populated
The reason your path already has some entries in it is due to your system shell files setting path for you. This is covered in a couple other posts:
Why and where the $PATH env variable is set?
Where is the source of $PATH? I cannot find it in .zshrc
one liner, without opening ~/.zshrc file
echo -n 'export PATH=~/bin:$PATH' >> ~/.zshrc
or
echo -n 'export PATH=$HOME/bin:$PATH' >> ~/.zshrc
To see the effect, do source ~/.zshrc in the same tab or open a new tab
Added path to ~/.zshrc
sudo vi ~/.zshrc
add new path
export PATH="$PATH:[NEW_DIRECTORY]/bin"
Update ~/.zshrc
Save ~/.zshrc
source ~/.zshrc
Check PATH
echo $PATH
OPTION 1: Add this line to ~/.zshrc:
export "PATH=$HOME/pear/bin:$PATH"
After that you need to run source ~/.zshrc in order your changes to take affect OR close this window and open a new one
OPTION 2: execute it inside the terminal console to add this path only to the current terminal window session. When you close the window/session, it will be lost.
If you are on macOS (I'm on Monterey 12.3.1), you may have been pulling your hair like I did metaphorically. These instructions above all worked for me within the terminal session, but I could never get it to persist no matter what I did with export. Moreover, I couldn't find the .zshrc anywhere.
Turns out Apple does it differently. The file you need to edit is etc/paths. You can simply sudo nano /etc/paths and add your path in a new line. Then simply restart terminal and voila.
for me PATH=$PATH:/path/to/file/bin
then export PATH worked.
to check echo $PATH . other solutions are adding the path temporarily.
I'm on Monterey 12.4 and the only way I could change the path was using the helper function. Editing text files in nano did diddly squat
# append
path+=('/foo/bar/yourpath')
# export to sub-processes
export PATH
to verify your new directory has been added correctly, you can use
print -l $path
thanks to the fact that its type is known to be an array
how to append new plugin to zshrc file. I tried the below syntax but it replaced with new one.
sed -i -e 's/plugins=(.*)/plugins=(zsh-syntax-highlighting)/' ~/.zshrc
I want to add git, file, docker etc.
pl give me the corrected syntax.
KSK

Difference between using JAVA_HOME=... and export JAVA_HOME=$(...)

Up until now I've been setting environmental variables using something like:
JAVA_HOME=...
From this https://xenovation.com/blog/development/java/how-to-set-java-home, I can set it using:
export JAVA_HOME=$(/usr/libexec/java_home)
Could someone explain:
Why echo $JAVA_HOME shows /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home
I understand that export JAVA_HOME=... sets an environment variable. What does adding $(...) do?
Would export JAVA_HOME=(/usr/libexec/java_home) be the same thing as export JAVA_HOME=/usr/libexec/java_home?
Thank you!
1- /usr/libexec/java_home is an executable that can give you proper value for JAVA_HOME, it also can be used by arguments. for example /usr/libexec/java_home -v '1.7*' will give you sutiable value for JAVA_HOME in order to use Java 7. $(/usr/libexec/java_home) will give you path to JAVA_HOME which in your case will be /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home.
2- $(...) is for command substitution. for example:
a=$(echo foo) # results a="foo"
3- they're not the same in concept! export JAVA_HOME=(/usr/libexec/java_home) will assign an array to JAVA_HOME but export JAVA_HOME=/usr/libexec/java_home ill assign an string path to it. if you echo $JAVA_HOME it will show the first element of array which in your case because you have only one element, it will result into the same thing. It means export JAVA_HOME=(/usr/libexec/java_home) and export JAVA_HOME=/usr/libexec/java_home will be the same.
NOTE: /usr/libexec/java_home is only a binary file which points to real JAVA_HOME. you must execute it with export JAVA_HOME=$(/usr/libexec/java_home) to get true result!

Java_HOME not found when changed shell from Bash to Zsh on OSX?

This is weird, I have set JAVA_HOME for my mac which can be found when I am using bash shell, but if I change shell, I get a message saying JAVA_HOME not set. What could be going on here?
I stumbled upon your question when trying to solve the same issue while migrating from bash to oh-my-zsh. The reason it's not there is that there is no code setting it for zsh but there was for bash. Generally theres something exporting JAVA_HOME whenever a new bash window is opened so it's always set for you. There is a good thread where this might be happening on the Unix & Linux StackExchange site.
To do the same thing in zsh, you can edit the .zshrc which is run every time zsh starts. I found a sample .zshrc which got me most of the way. The key line being:
export JAVA_HOME=`/usr/libexec/java_home`
Here is the file which I appended to the end of my existing ~/.zshrc file:
#zshrc, interactive shell settings
export ZSH=$HOME/.zsh
# emacs integration
[[ $EMACS = t ]] && unsetopt zle
# env
if [[ -e /usr/libexec/java_home ]]; then
export JAVA_HOME=`/usr/libexec/java_home`
fi
if [[ -e /usr/local/lib/node_modules ]]; then
export NODE_PATH=/usr/local/lib/node_modules
fi
# path
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11/bin
export PATH=/opt/usr/sbin:/opt/sbin:/opt/usr/bin:/opt/bin:$PATH
export PATH=/usr/local/bin:/usr/local/sbin:$PATH
export PATH=$HOME/.cabal/bin:$PATH
export PATH=$HOME/.gem/ruby/1.8/bin:$PATH
export PATH=$JAVA_HOME/bin:$PATH
export PATH=$HOME/.bin:$PATH
setopt null_glob
# source all files in zsh root
for include in $ZSH/*.zsh; do
source $include
done
# source all non-controlled files
for include in $ZSH/private/*.zsh; do
source $include
done
unsetopt null_glob
Then source ~/.zshrc to run in the current shell (or just start a new one) and you should be able to see that it is set with export | grep JAVA_HOME.
I also ended up running mkdir ~/.zsh to create the directory this is looking for and removing the .cabal and .gem lines as they were not needed for me.
I have just installed Mac OS Catalina Version 10.15 and found that environment variables such as JAVA_HOME and others that have been set in my .bash_profile :
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home
export PATH=$JAVA_HOME/bin:$PATH
export ANDROID_HOME=/Users/mynziak/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools
export M2_HOME=/usr/local/Cellar/maven/3.6.2/libexec
export M2=${M2_HOME}/bin
export PATH=${PATH}:${M2_HOME}/bin
are not set in fact!
I saw % in terminal instead of general $ that means you are using a zsh shell instead of bash shell. With Catalina zsh is now the default shell and bash will be completely gone in the future.
oh-my-zsh shell:
https://ohmyz.sh/
So you have to setup all environment variables in .zshrc file.
I just copy-pasted every variables from .bash_profile in to .zshrc and re-opened terminal.
Files .bash_profile and .zshrc are hidden (cmd+shift+. - show hidden files in finder) but can be found in path:
/Users/mynziak/.zshrc
but use own username!
When you set JAVA_HOME in a shell, then it is active and available only for that context, and it will be gone when you close that shell.
Instead either change global environment (or) your .bashrc to include it. So that every time you start a shell, the variable will be available.
edit the .profile or .bash_profile to include the JAVA_HOME.
export JAVA_HOME=`/usr/lib....`
and also below command will return the path for java home directory.
/usr/libexec/java_home -v 1.7
where 1.7 is the version you want.
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
export PATH=$JAVA_HOME/bin:$PATH
Add above 2 lines in ~/.bashrc or ~/.zshrc and reload the file using source command.

Setting PATH environment variable in OSX permanently

I have read several answers on how to set environment variables on OSX permanently.
First, I tried this, How to permanently set $PATH on Linux/Unix but I had an error message saying no such file and directory, so I thought I could try ~/.bash_profile instead of ~/.profile but it did not work.
Second, I found this solution How to set the $PATH as used by applications in os x , which advises to make changes in
~/.MacOSX/environment.plist
but again I had no such file and directory error.
I need a way to set these variables such that it won't require setting them again and again each time I open a new terminal session.
You have to add it to /etc/paths.
Reference (which works for me) : Here
I've found that there are some files that may affect the $PATH variable in macOS (works for me, 10.11 El Capitan), listed below:
As the top voted answer said, vi /etc/paths, which is recommended from my point of view.
Also don't forget the /etc/paths.d directory, which contains files may affect the $PATH variable, set the git and mono-command path in my case. You can ls -l /etc/paths.d to list items and rm /etc/paths.d/path_you_dislike to remove items.
If you're using a "bash" environment (the default Terminal.app, for example), you should check out ~/.bash_profile or ~/.bashrc. There may be not that file yet, but these two files have effects on the $PATH.
If you're using a "zsh" environment (Oh-My-Zsh, for example), you should check out ~./zshrc instead of ~/.bash* thing.
And don't forget to restart all the terminal windows, then echo $PATH. The $PATH string will be PATH_SET_IN_3&4:PATH_SET_IN_1:PATH_SET_IN_2.
Noticed that the first two ways (/etc/paths and /etc/path.d) is in / directory which will affect all the accounts in your computer while the last two ways (~/.bash* or ~/.zsh*) is in ~/ directory (aka, /Users/yourusername/) which will only affect your account settings.
Read more: Mac OS X: Set / Change $PATH Variable - nixCraft
For a new path to be added to PATH environment variable in MacOS just create a new file under /etc/paths.d directory and add write path to be set in the file. Restart the terminal. You can check with echo $PATH at the prompt to confirm if the path was added to the environment variable.
For example: to add a new path /usr/local/sbin to the PATH variable:
cd /etc/paths.d
sudo vi newfile
Add the path to the newfile and save it.
Restart the terminal and type echo $PATH to confirm
You can open any of the following files:
/etc/profile
~/.bash_profile
~/.bash_login (if .bash_profile does not exist)
~/.profile (if .bash_login does not exist)
And add:
export PATH="$PATH:your/new/path/here"
You could also add this
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
to ~/.bash_profile, then create ~/.bashrc where you can just add more paths to PATH. An example with .
export PATH=$PATH:.
If you are using zsh do the following.
Open .zshrc file nano $HOME/.zshrc
You will see the commented $PATH variable here
# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/...
Remove the comment symbol(#) and append your new path using a separator(:) like this.
export
PATH=$HOME/bin:/usr/local/bin:/Users/ebin/Documents/Softwares/mongoDB/bin:$PATH
Activate the change source $HOME/.zshrc
You're done !!!
sudo nano /etc/paths
now find the path of command i am giving an example of setting path for flutter.
/Users/username/development/flutter/bin
now cntrol+x and then y . reopen the terminal and check.
launchctl setenv environmentvariablename environmentvariablevalue
or
launchctl setenv environmentvariablename `command that will generate value`
use proper ` and remember to restart application or terminal for the environment variable to take effect.
you can check environment variable by printenv command.
note : environment variable named path is already set by someone else so we are not appending anything to that path at all here.
shows all hidden files like .bash_profile and .zshrc
$ ls -a
Starting with macOS Catalina, mac uses zsh instead of bash. so by default mac uses zsh.
Check which shell running:
$ echo $SHELL
/usr/zsh
$ cd $HOME
$ open -e .zshrc
or if using vim
$ vi .zshrc
Then add it like this
$ export my_var="/path/where/it/exists"
$ export PATH=$PATH:/$my_var/bin
For example: if installed app named: myapp in /Applications
Then
export MYAPP_HOME=/Applications/myapp
export PATH=$PATH:$MYAPP_HOME/bin
or shortcut
export PATH=${PATH}:/Applications/myapp/bin
TADA you set for life !!! Thank me later
19 October 2021.
Confirming iplus26's answer with one correction.
Test environment
OS: macOS 11.6 (Big Sur) x86_64
Shell: zsh 5.8
Below is the order in which the $PATH environment variable is modified:
each line in etc/paths text file gets appended
each line in each text file inside etc/paths.d directory gets appended
finally, the $PATH is further modified in ~/.zshrc
iplus26's answer stated "when (you run) echo $PATH, The $PATH string will be PATH_SET_IN_3&4:PATH_SET_IN_1:PATH_SET_IN_2" but this isn't always the case. It will have to depend on what the script is doing inside .zshrc. E.g. If we do something like
PATH="/new/path:${PATH}"
then, the new path will be in the beginning of the path list. However, if we do something like
PATH="${PATH}:/new/path"
then, the new path will be appended at the end of the path list.
Of course, you'll have to make sure you export the modified path in the ~/.zshrc file.
export PATH=$PATH
One handy command you could use to "pretty print" your path list is
print -l $path
This will print each path on a new line for better readability. Note $path is like $PATH except it's delimited by a single space, instead of a colon, :.
Hopefully this can further clarify for newcomers to this thread.
For setting up path in Mac two methods can be followed.
Creating a file for variable name and paste the path there under
/etc/paths.d and source the file to profile_bashrc.
Export path variable in ~/.profile_bashrc as
export VARIABLE_NAME = $(PATH_VALUE)
AND source the the path. Its simple and stable.
You can set any path variable by Mac terminal or in linux also.

Cygwin shell doesn't execute .bashrc

After start the cygwin shell, it just locate in a wrong home dir:
xfire#codingme.com ~
$ pwd
/cygdrive/c/Users/xfire
But it used to be /home/xfire
xfire#codingme.com /etc
$ cat passwd | grep xfire
xfire:unused:22773:10513:U-CORP\xfire,S-1-5-21-527237240-725345543-682003330-12773:/home/xfire:/bin/bash
And the .bashrc in the /home/xfire was not executed, even I copy it to the /cygdrive/c/Users/xfire, it also doesn't work!
On cygwin, I add this to my ~/.bash_profile:
. ~/.bashrc
Some program add an "HOME" environment in windows registry and set the value to "C:\Users\xfire", that's why cygwin take that directory as the home. cygwin.com/faq-nochunks.html
On my version of cygwin I found that only ~/.profile was being execueted so added
if [ -e "${HOME}/.bash_profile" ]; then
source "${HOME}/.bash_profile"
fi
to the .profile file. My .bash_profile file contains another test for .bashrc and executes that from inside there. I also added the following two lines to my .bashrc file.
export BASH_ENV="${HOME}/.profile"
export ENV="${HOME}/.profile"
The first of these ensures that .profile gets executed in non-interactive terminals and the second ensures it gets executed in POSIX terminals. I found a very useful explanation of what get run and when in the Bash Reference Manual.
In your case it wouldn't help as you have an issue with the value of your HOME environment variable but this page comes up quite high on the list when searching for this issue.
You can also also set BASH_ENV variable, e.g., BASH_ENV='C:\DOCUME~1\dwyttenb\.bashrc'
~/.bash_profile is executed before the initial command prompt is returned to the user. After that, every time a new shell is opened, ~/.bashrc is executed.
Adding . ~/.bashrc at end of ~/.bash_profile has resolved the problem.
Now you can check existing aliases using alias command.
Find more details on github.

Resources