24

I'm using zsh as my shell, and I'm trying to configure my environment.

I usually define my $JAVA_HOME variable by creating a file:

/etc/profile.d/java.sh

with the following content

export JAVA_HOME=/path/to/jdk
export PATH=$JAVA_HOME/bin:$PATH

then I logout and back in, and it all works, but for some reason the PATH variable is not set. It recognizes JAVA_HOME, but not the new PATH, see this terminal snippet:

~  echo $JAVA_HOME
/usr/lib/jvm/jdk1.8.0_05
~  echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

and I confirmed it by trying to run a command form the jvm

~  java -version
zsh: command not found: java

the PATH doesn't include the $JAVA_HOME as it should. is there something else I should check?

I have checked that if I run:

source /etc/profile.d/java.sh

it all runs correctly and my variables get set as they should, but shouldn't the scripts in /etc/profile.d run automatically?

1
  • 1
    Have you tried editing ~/.profile and placing the variables there instead? It may be that PATH is being overwritten elsewhere in /etc/profile.d/. Jun 3, 2014 at 14:34

4 Answers 4

33

From my point of view, the best way is to add the following lines at the ~/.zshrc file (if you don't already have it, then create it):

if [ -d "/path/to/jdk" ] ; then
    export PATH="/path/to/jdk/bin:$PATH"
fi

Then restart your zsh, or just run source ~/.zshrc and then your PATH should be exactly as you wish.

Or, if you want to make the change to be system-wide, then add the previous code to the end of /etc/zsh/zshenv file.

But in any case do not use /etc/profile.d to automatically run scripts in zsh. This directory is useful only for the bash shell, not zsh as in your case. To understand this, open /etc/profile file, which is a bash initialization file and in no case a zsh initialization file, and you will see somewhere at the end of the file:

if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi

So, your scripts from /etc/profile.d directory will automatically run in zsh only if you add the previous code in a zsh initialization file, like /etc/zsh/zprofile for example, or source /etc/profile in /etc/zsh/zprofile file.

4
  • 6
    Perhaps ~/.zprofile might be better than ~/.zshrc.
    – muru
    Jan 18, 2015 at 13:37
  • If there is a /etc/profile.d then all scripts in there are run anyway regardless of zsh. Or they are on debian.
    – RichieHH
    Dec 3, 2020 at 11:03
  • Your link to a zsh initialisation file is dead.
    – GarethAS
    Aug 9, 2021 at 12:04
  • @RichieHH I'm on zsh and there are scripts in /etc/profile.d which aren't run, despite having the right permissions.
    – amzon-ex
    Nov 4, 2022 at 7:05
4

I find that placing everything in one .zshenv file quickly becomes hard to manage. I recommend installing oh-my-sh and then placing various customizations (env vars, functions) to the .oh-my-sh/custom/ directory as separate .zsh files.

I also discovered that this approach works flawlessly when ssh'ing into machine when modifying env variables such as PATH. Also it works really nice together with vcsh for keeping customizations backed up and in sync.

3
  • Using oh my zsh framework, where would you put a variable with an ip adress (remote server) to use for ssh access? I need the ip for git and a login script to the server.
    – Timo
    Dec 20, 2017 at 11:12
  • 1
    Hm. Not quite sure what you mean. I would put the config like ip addresses and usernames for ssh to ~/.ssh/config
    – dvim
    Jan 16, 2018 at 15:55
  • I personally prefer this approach to the accepted answer as I like the advantage of using vcsh and the "custom" folder for ZSH is an ideal place for stuff like this. Oct 3, 2019 at 18:52
1

Since JAVA_HOME is set, you have confirmed that those scripts are sourced automatically, haven't you?

The only logical explanation is that PATH is set later on somehow. It should be originally set by PAM which reads /etc/environment, and as far as I know that happens before /etc/profile.d/*.sh files are sourced. Possibly zsh works different compared to bash in that respect.

0

Just ran into this issue locally after running updates. Looks like the root issue is Drush doesn't know where to find a legit copy of php that includes pdo. Fortunately it supports stashing this path in an environment variable, so I did this on the commandline:

export DRUSH_PHP="/Applications/MAMP/bin/php/php5.4.39/bin/php"

That fixed the issue so I edited .zshrc and added that to the file, problem solved.

1
  • 1
    So, you're suggesting that .zshrc be used, the same as the top answer?
    – muru
    Apr 23, 2015 at 17:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .