After installing some programs in /opt/xxx/bin, I want to add /opt/xxx/bin to system $PATH for all users's non-login shell. What should I do?


On Debian and other systems that use PAM (which is most of them nowadays), you can set environment variables (including PATH) in /etc/environment. This will work for any login method that uses the pam_env module (either in the auth section or in the session section); on Debian that should be all of them (at least the ones that provide ways to log in and run commands).


The default path could be set in /etc/profile like Joe said but also in $HOME/.profile. I also have plenty of packages i compiled on my own (with the common procedure ./configure --prefix=/opt/<name>) installed in /opt. To execute the binaries in /opt/<name>/bin without any additional effort I added


for i in $OPTDIR/* ; do
    if [ -d $BINDIR ] ; then
        if [ -z $PATH ] ; then

export PATH

to my $HOME/.profile which in your case would be /etc/profile. Now even if i install packages under /opt in the future i don't have to worry about accessing the related binaries in /opt/.*/bin since the path is automatically added to $PATH.

Because the additional software is not necessary stable i prefer $HOME/.profile over /etc/profile.

A small remark: /etc/.profile respectively $HOME/profile is not executed by your default shell but by dash. A lightweight variant of bash which reduces the load during the boot process.

  • Neither /etc/profile nor ~/.profile is not executed by non-login shell. – Yang Bo Sep 10 '12 at 0:33
  • You are right, my answer is not fully related to your question. I just described what i did to get things running. If you aren't using X my approach does what you want since every non-login shell is a child-process of the login-shell. If you are using X you can source the little script i have posted in the init file of your display manager (in most cases Xsession). Now every child process of the display manager have the defined $PATH variable. In the described two cases my approach definitely works and you can access every binaries under /opt/.*/bin. – user1146332 Sep 10 '12 at 8:53

I found the most excellent answer on serverfault by Gilles:

How set PATH for all users in Debian?

The first place where PATH is set is /etc/login.defs. There's a setting for root and a setting for everyone else.

Another place where you can define environment variables is /etc/environment. These settings will apply to everyone (you can't write arbitrary shell code there).

A third place where you can define environment variables is /etc/profile. There you can write arbitrary shell code. If you want a user-specific setting, there is the corresponding per-user file ~www-data/.profile. But this will only apply to console interactive logins; in particular it won't apply to cron jobs unless they explicitly source /etc/profile.

If you only need that PATH setting in a user crontab, you can write it at the beginning of the crontab. Note that you need the full list (PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/zend/bin), you can't use a variable substitution (PATH=$PATH:/usr/local/zend/bin won't work there).


The default path can be set in /etc/profile

But I was just looking on my Ubuntu system, and it's set in /etc/environment

  • 2
    /etc/profile is not executed by non-login shell. – Yang Bo Sep 10 '12 at 0:30

su command resets your PATH environment value to one defined in /etc/login.defs by ENV_PATH and ENV_SUPATH variables. don't forget to configure this file. see here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.