210

I have a program that is installed in a custom directory under /opt. To make it easier to run it, I edited my bashrc to add said directory to my path:

export PATH=$PATH:/opt/godi/bin:/opt/godi/sbin

This works fine if I want to run the program without sudo. However, if I try to run it with sudo it fails with a "command not found" error.

$ sudo godi_console
sudo: godi_console: command not found

Inspecting the PATH variable after using sudo reveals that its not including the same PATH I have as a normal user:

$ sudo sh
# echo $PATH                 
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Why is the PATH not the same? Am I doing something wrong? I'm on Debian Jessie, if it makes a difference.

One thing I tried was to invoke /opt/godi/sbin/godi_console directly, passing the absolute path to the executable. Unfortunatelly, that didn't help in this particular case because godi_console itself depends on the PATH being correctly set.

6

9 Answers 9

259

You can always do:

sudo env "PATH=$PATH" godi_console

As a security measure on Debian, /etc/sudoers has the secure_path option set to a safe value.

Note that:

sudo "PATH=$PATH" godi_console

Where sudo treats leading arguments containing = characters as environment variable assignments by itself, would also work at running godi_console with your $PATH (as opposed to the secure_path) in its environment, but would not affect sudo's search path for executable, so wouldn't help sudo in finding that godi_console.

7
  • 7
    I like this answer best since it avoids need to change settings globally (i.e. preserves principle of least privilege) Mar 11, 2015 at 0:31
  • 7
    sudo "PATH=$PATH" godi_console did not work in CentOs7 by the way. Needed the env
    – Hakan Baba
    Jan 25, 2018 at 6:29
  • 2
    @StéphaneChazelas Does sudo "PATH=$PATH" godi_console ever really work? sudo accepts VAR=value arguments, affecting the environment of the command it runs, but unlike in env or bash, sudo doesn't seem to let this affect how it looks up the command. I only tested this (recently) on Ubuntu 16.04. But I tried adding the exempt_group option to sudoers (just for testing--I don't consider this a solution!) and the results were illuminating. Commands of the form PATH="$PATH" sudo some-command started working, but those of the form sudo PATH="$PATH" some-command still did not. Apr 13, 2018 at 11:32
  • 2
    @ballsatballsdotballs. As that alias should only affect your interactive shells, that should be relatively harmless. Apr 15, 2018 at 13:43
  • 5
    I just create an alias called psudo for these types of cases, where: alias psudo="sudo env \"PATH=$PATH\"". Then my normal sudo use is unaffected.
    – mikeTronix
    May 18, 2018 at 18:38
64

You can also set the default PATH at /etc/sudoers

edit the file using visudo

and update the line to what ever you wish: Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin

3
  • This is a good way. See also superuser.com/questions/927512/…
    – flow2k
    Apr 10, 2021 at 2:01
  • At least on a RHEL system this would be better done with a file in /etc/sudoers.d/ adding onto the system default. I assume Debian would be similar.
    – miken32
    Jan 20, 2023 at 19:30
  • e.g. echo 'Defaults secure_path="/sbin:/bin:/usr/sbin:/usr/bin:/my/custom/path"' > /etc/sudoers.d/custom_path
    – miken32
    Jan 20, 2023 at 23:12
29

SUDO is doing env variables reset by default.

Check out its manual and option called env_reset.

You just need to disable it in /etc/sudoers.

3
  • 9
    Cool! In Ubuntu you can visudo and comment out the secure_path and env_reset lines. Makes the system considerably less secure, so beware.
    – RawwrBag
    Mar 29, 2016 at 18:29
  • Disabling env_reset seems not to affect sudo's behaviour w/r/t PATH.
    – Zanna
    Apr 13, 2018 at 11:40
  • 1
    You have to comment secure_path as well, as mentioned by @RawwrBag Dec 21, 2019 at 6:18
21

This works :

sudo $(which your_command)

Example calling my gps script which lists Nvidia GPU's processes :

$ sudo gps
sudo: gps: command not found
$ sudo $(which gps)
  PID TTY          TIME CMD
 9922 tty7     02:42:47 Xorg

Explanation :

$ set -x;sudo $(which gps);set +x
++ which gps
+ sudo /home/xyztuv/myScripts/shl/gps
  PID TTY          TIME CMD
 9922 tty7     02:42:39 Xorg
+ set +x
5
  • 2
    This is the best answer because it doesn't expose you to other commands on your path being hijacked. All of the other answers here risk running other executables as root. Jan 14, 2021 at 14:08
  • Unless the command you're using calls other commands that it expects to find in $PATH - then you want to be "hijacked", and so the other answers are better.
    – Dave Morse
    Jan 18, 2022 at 4:11
  • @DaveMorse Yes, in that sense, my example is not secure but then the question of How to make "sudo" preserve $PATH? is not a secure idea either.
    – SebMa
    Jan 18, 2022 at 9:16
  • using absolute path avoid PATH problem. in general purpose a smart move
    – Kevin Chan
    Oct 11, 2022 at 7:07
  • I don't know that it's the best answer. It's a good answer. The reason why is some scripts start with something like #!/usr/bin/env python3 and this answer won't help make sure you get the right python3, like for a virtual environment. Jul 12, 2023 at 15:30
13
sudo --preserve-env=PATH env [command]

this ovverrides secure_path on my end

2

Here's what worked for me on Ubuntu.

Put this near the bottom of your ~/.bashrc:

mysudo() {
        cmd=$(which $1)
        shift
        sudo "$cmd" $@
}

alias sudo="mysudo"

Then log out and log back in, or do:

source ~/.bashrc

After that sudo works properly, like it does on other distros such as Debian.

On second thought, this is not supporting sudo's command line switches, so if you need those, you could expand on this and make something a bit more complex to support it.

1

This worked:

sudo "PATH=$PATH" [your command]

Do not change $PATH with your path value, you just write it this way

example: $ sudo env "PATH=$PATH" ant -f webAppConfig.xml regenWebAppConf....

1

Maybe not precisely what OP asks for, but this might help:

sudo -u the_user sh -c 'PATH=$PATH:/opt/godi/bin echo $PATH'

This changes the PATH inside the sudoed command.

0

Whilst this might not entirely be what op wants, I believe the best option is to call

sudo /opt/godi/sbin/godi_console

That way you are certain you are calling the correct binary, and not one that someone sneaked into your path somewhere.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .