Lately I encountered a problem with IntelliJ on macOS I wasn’t aware of so far. For a new project I joined it was necessary to let Java execute a shell script which resides in /usr/local/bin and calls another script. Putting all the questions for the reason behind this aside I was pretty puzzled when I couldn’t get this to work while on all my colleagues Linux machines it worked like a charm.
After fiddling around with it for a while it became very much clear that the JVM which I started from IntelliJ didn’t had /usr/local/bin in its PATH environment variable and because of that couldn’t execute the script. The question was why this was the case. When I started the application via gradle on the shell everything worked correct which seemed to point to an IntelliJ problem. After some research it became clear that the root cause of the problem is a concept in macOS which separates the shell environment variables from the environment variables for GUI processes, or better said the environment variables for processes which are started from Spotlight, Finder or the desktop.
The standard environment variables set for GUI applications on macOS are controlled via launchctl and are per default set to /usr/bin:/bin:/usr/sbin:/sbin.
The quick solution to get around this and use the environment variables set in the Shell via .bashrc or .zshrc etc. is to start IntelliJ (or any other UI application) via the command line. This can be done on with the command
open /Applications/IntelliJ\ IDEA.app
After that IntelliJ runs in the shell context and has access to all the variables set there. If this doesn’t suit you and you want a more permanent solution which makes it possible to start IntelliJ without the shell and still have access to the environment variables there is a solution for that, too.
You have to create the file ~/Library/LaunchAgents/environment.plist. A plist file in macOS is a property list file which is a widely used concept in macOS (read more about it here). In this file there can be some startup configurations stored. A minimal configuration to just control the environment variables could look like this:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>my.startup</string> <key>ProgramArguments</key> <array> <string>sh</string> <string>-c</string> <string> launchctl setenv PATH /usr/local/bin:$PATH </string> </array> <key>RunAtLoad</key> <true/> </dict> </plist>
This adds the path /usr/local/bin to the existing path. For the configuration to be active it is necessary to restart macOS. After that the new path should be available for all GUI applications no matter if started from Finder, Spotlight or whatever.