Making applications available in non-login shells

Assuming commands should be executed on a remote computer using ssh these commands have to be available in the PATH variable. This is not a problem with locally installed tools and commands on Linux systems but when custom programs should be executed this can get a little bit tricky.

When you log in as a user the full profile is loaded. This means all defined PATH variables are set. But when a command is executed via ssh the profile is not loaded completely. The following command shows how this works:

ssh user@host 'echo "Hello World"'
Hello World

This gets executed without a problem, but as soon as a third party application, like Java, is launched, something like this could appear:

ssh user@host 'java --version'
bash: java: Command not found.

The problem here is, that the path to the Java executable is not in the global Path and thus the executable can not be found and executed. So how do you make it look like this?

ssh user@host 'java --version'
openjdk 11.0.10 2021-01-19 LTS
OpenJDK Runtime Environment Zulu11.45+27-CA (build 11.0.10+9-LTS)
OpenJDK 64-Bit Server VM Zulu11.45+27-CA (build 11.0.10+9-LTS, mixed mode)

The trick is in the file


In this file you can find the bold line.

export JAVA_HOME=/opt/java/stable
export PATH=$JAVA_HOME/bin:$PATH

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Everything that should also be loaded in non-interactive shells, like the one used with the ssh command, must be placed above this line.

In this case JAVA_HOME is set to a custom Java installation (/opt/java/stable which is a symlink to a directory containing the application) and then this path is used in the global PATH variable.