I installed xampp in my system in the location /opt/lampp
. After that I added the php location to my path variable using
export PATH=$PATH:/opt/lampp/bin
So when I run php -v
using terminal I get the expected output.
PHP 5.6.8 (cli) (built: Apr 20 2015 18:37:47)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
But when I run sudo php -v
I get this:
sudo: php: command not found
I don't know why this happens. Am I doing something wrong while adding it to path variable?
Edit:
This question is not a duplicate of Environment variables when run with 'sudo', because in that question zetah asked how to pass arbitrary variables to a python command. They are able to execute python
using sudo
, but I can't execute php
using sudo
.
Following this answer, I added the PATH to sudo
using the following command:
sudo PATH=$PATH:/opt/lampp/bin php -v
but I am getting the output as before:
sudo: php: command not found
Following this answer, I added -E
to sudo
, but I get the same result:
$ sudo -E php -v
sudo: php: command not found
Best Answer
Why
sudo
doesn't use your PATHThe reason
sudo
ignores your PATH variable is that it has its ownsecure_path
, and it's fairly determined to use it.If you
sudo cat /etc/sudoers
or justsudo grep secure /etc/sudoers
, you'll see what this path is on your system. I have this line:The purpose of
sudo
'ssecure_path
is to try to make it less likely that a user withsudo
privilege will (accidentally) run dangerous code as root after their path has been modified, perhaps to include local directories.It's possible to avoid
sudo
using thesecure_path
altogether by modifying/etc/sudoers
to comment out that line, but that would be a bad idea because it removes a security measure, and it's also unnecessary because you can easily work around it in various preferable ways.Getting
sudo
to use your PATHTo override the
secure_path
and makesudo
use your PATH as currently defined, as muru commented, you can use:Note that the
-E
flag or merely assigning the variable do not work (on Ubuntu at least).When adding to PATH, use the absolute path (the shell will expand
~
before assigning the variable). I don't need toexport
(and doing so does not help), because PATH is already exported, and changing its value will cause child processes to inherit the change too.It's often expected that this will work...
man sudo
says:But that doesn't work. The
-E
flag has no effect onsecure_path
, which is possibly a bug.This does not affect
sudo
's own environment, which has been set according to the security policy, configured by/etc/sudoers
. This includesenv_reset
andsecure_path
as defaults on Ubuntu, causing a minimal environment to be loaded and the PATH to be set to whatever is insecure_path
.If
sudo
were able to find a command calleduseless
in one of its own path directories and run it, it would passPATH=$PATH
into its environment as demonstrated here. But it will not itself use the given value of PATH. The solution is to run:This workaround uses the
env
command to set PATH. Unlikesudo
,env
uses the given variables to set the environment, then looks for the command argument and runs the command with the modified environment. Asinfo (coreutils) env invocation
says:Setting the PATH
When you changed your PATH variable to include the directory
/opt/lampp/bin
, you used this command:This would be effective for the current shell and all the current shell's child processes, such as shells called from this shell. When you've exited this shell and all its children have exited, that modified PATH variable has been thoroughly forgotten, and when you open a new shell you will find the old PATH variable that does not include
/opt/lampp/bin
. For that reason, the full command suggested by muru,would have been necessary if you were not still using a shell where you had already added
/opt/lampp/bin
.To change the path permanently, you would need to edit some configuration file that modifies your user environment or is read by shells when they start up. You can add a line to assign environment variables in your
~/.profile
, for example:Then, after logging out and back in (or running
source ~/.profile
to see the effect immediately), you would always be able to runor
without adjusting your PATH first.
Less cumbersome alternatives
A more convenient workaround could be to make a symlink to the executable in a location that is in the
secure_path
and the default PATH, for example:You will then not need to do anything special when calling the command with
sudo
, nor will you ever need to take any steps to adjust your PATH, permanently or temporarily.If the program you are installing has a name that is the same as the name of another program that system processes may attempt to call, then give the symlink a different name, to avoid confusing those processes. You can check that the name you want to use is not already the name of some other command using the
type
command:So on this system I can create a command
php
without fear of anything going wrong, at the moment. If I install other programs that provide aphp
command in future, I might have to re-think my configuration.You could also make an alias for the command and add it to your
~/.bashrc
, for example:You could then (after running
source .bashrc
or opening a new shell) runinstead of
sudo php
to run this program as root, andsudo
will not claim to be ignorant of its location.This alias would only be available in interactive shells, so it wouldn't confuse other programs.
Of course, it's possible to make an alias for just
sudo
to make it always use your PATH, withalias sudo='sudo env PATH="$PATH"'
, but that's a bad idea as it would make the system less secure.