2

Can anybody explain why this:

sudo env "PATH=$PATH" make install

is not the same as this:

sudo make install

?

I had a situation recently where make install failed unless run as shown above. The error had something to do with libtool, but that's sort of besides the point - why does sudo env "PATH=$PATH" do anything whatsoever? Shouldn't PATH already be in the environment from my shell session?

1 Answer 1

5

It's normal for sudo to ignore the PATH it got in the environment.

When you run sudo some_command, sudo uses its own set of directories instead of PATH. This set may or may not be defined somewhere in sudo config (/etc/sudoers, /etc/sudoers.d/*). If it's not explicitly defined, /etc/sudoers says the default value is

secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

(This is somewhat simplified, other options may alter this mechanics; see man 5 sudoers for details).

Not only sudo uses its own PATH to locate executables; also commands run by sudo inherit this other PATH, not your original PATH from the shell.

env foo=bar baz is a way to set the variable foo to the value of bar for the command baz. When you do

sudo env "PATH=$PATH" make install

the shell expands $PATH. sudo resets the variable for env, but env gets your old expanded value inside the PATH=… command line argument. This way you inject your PATH into the environment of make, circumventing the fact sudo changes PATH (still the other value of PATH matters elsewhere: sudo uses it to search for env executable in the first place).

You may be able to achieve a similar result with

sudo "PATH=$PATH" make install

but variables passed this way are subjects to restrictions imposed by the security policy plugin for sudo. What you did with env is not restricted.


Compare outputs from these (note sole env prints its environment):

export foo=bar
                         env | grep '^foo='
             env foo=qux env | grep '^foo='
sudo                     env | grep '^foo='
sudo foo=baz             env | grep '^foo='
sudo         env foo=qux env | grep '^foo='
sudo foo=baz env foo=qux env | grep '^foo='

Another set to compare:

                      env | grep '^PATH='
sudo                  env | grep '^PATH='
sudo     "PATH=$PATH" env | grep '^PATH='
sudo env "PATH=$PATH" env | grep '^PATH='

In general, depending on your PATH and settings of sudo the results may or may not be identical. In your case I expect them to differ (because the two commands in question worked differently).

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.