Why sudo
doesn't use your PATH
The reason sudo
ignores your PATH variable is that it has its own secure_path
, and it's fairly determined to use it.
If you sudo cat /etc/sudoers
or just sudo grep secure /etc/sudoers
, you'll see what this path is on your system. I have this line:
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
The purpose of sudo
's secure_path
is to try to make it less likely that a user with sudo
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 the secure_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 PATH
To override the secure_path
and make sudo
use your PATH as currently defined, as muru commented, you can use:
sudo env PATH="$PATH" command
Note that the -E
flag or merely assigning the variable do not work (on Ubuntu at least).
$ mkdir junk # create a test directory to add to PATH
$ echo "echo foo" > junk/useless # create a harmless program
$ chmod u+x junk/useless # make it executable
$ PATH="$PATH":~/junk # add directory to PATH
When adding to PATH, use the absolute path (the shell will expand ~
before assigning the variable). I don't need to export
(and doing so does not help), because PATH is already exported, and changing its value will cause child processes to inherit the change too.
$ useless
foo
$ sudo useless
sudo: useless: command not found
$ sudo -E useless
sudo: useless: command not found
It's often expected that this will work... man sudo
says:
-E, --preserve-env
Indicates to the security policy that the user wishes to
preserve their existing environment variables.
But that doesn't work. The -E
flag has no effect on secure_path
, which is possibly a bug.
$ sudo PATH="$PATH" useless
sudo: useless: command not found
This does not affect sudo
's own environment, which has been set according to the security policy, configured by /etc/sudoers
. This includes env_reset
and secure_path
as defaults on Ubuntu, causing a minimal environment to be loaded and the PATH to be set to whatever is in secure_path
.
If sudo
were able to find a command called useless
in one of its own path directories and run it, it would pass PATH=$PATH
into its environment as demonstrated here. But it will not itself use the given value of PATH. The solution is to run:
$ sudo env PATH="$PATH" useless
foo
This workaround uses the env
command to set PATH. Unlike sudo
, env
uses the given variables to set the environment, then looks for the command argument and runs the command with the modified environment. As info (coreutils) env invocation
says:
Modifications to PATH
take effect prior to searching for command.
Setting the PATH
When you changed your PATH variable to include the directory /opt/lampp/bin
, you used this command:
export PATH=$PATH:/opt/lampp/bin
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,
sudo env PATH="$PATH:/opt/lampp/bin" php -v
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:
PATH="$PATH:/opt/lampp/bin"
Then, after logging out and back in (or running source ~/.profile
to see the effect immediately), you would always be able to run
php -v
or
sudo env PATH="$PATH" php -v
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:
sudo ln -s /opt/lampp/bin/php /usr/local/bin/php
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:
$ type php
bash: type: php: not found
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 a php
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:
alias sudo-php='sudo env PATH="$PATH:/opt/lampp/bin/php"'
You could then (after running source .bashrc
or opening a new shell) run
sudo-php
instead of sudo php
to run this program as root, and sudo
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, with alias sudo='sudo env PATH="$PATH"'
, but that's a bad idea as it would make the system less secure.
Best Answer
The error message
FATAL: Could not open '/home/iguarna/.local/share/TelegramDesktop/log_startXX.txt' for writing log!
shows that you did runtelegram
asroot
, and it created the log file (asroot
), now, the regular user cannot write to theroot
-owned log file. Fix this by:Where you run a program from is immaterial. Who you run a program as is important.