command not found when using sudo

56

21

There are a few question on the site that seem related to my problem but I could not find a solution in any of them.

My operating system is Ubuntu 12.04. I have mvn installed in /tools/noarch/apache-maven-3.1.1 and I have added the following lines at the end of my /etc/profile:

export M2_HOME=/tools/noarch/apache-maven-3.1.1
export PATH=$M2_HOME/bin:$PATH

After that I execute source /etc/profile.

Now my problem is: when I run mvn --version the command succeeds and mvn executable is found, while if I execute: sudo mvn --version I get the output: sudo: mvn: command not found. I know that PATH may be different when I execute a command with sudo and that is why I tried this:

$>sudo echo $PATH
/tools/noarch/apache-maven-3.1.1/bin:... some other stuff ...

Another thing I tried is to execute sudo su - and then type mvn --version. In this case mvn is successfully found and the command succeeds. What is going on here?

izomorphius Support Monica

Posted 2014-01-31T08:57:41.957

Reputation: 713

Related: Why are PATH variables different when running via sudo and su? at Unix SE

– kenorb – 2015-12-24T18:04:06.317

Answers

40

$PATH is evaluated by your shell, so your check doesn't work as you expect it to.

/etc/sudoers is configured to replace your PATH with a default one.

sudo does not load a login shell environment before executing the command, so the default PATH from /etc/sudoers is used. su - does open a login shell, which involves loading /etc/profile. See man bash, section INVOCATION.

Just remove the PATH reset in /etc/sudoers. It's likely a rule called secure_path.


CentOS

In CentOS you can add PATH to the Defaults env_keep section:

Defaults    env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR \
                        LS_COLORS MAIL PS1 PS2 QTDIR USERNAME \
                        LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION \
                        LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC \
                        LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS \
                        _XKB_CHARSET XAUTHORITY PATH"

Daniel Beck

Posted 2014-01-31T08:57:41.957

Reputation: 98 421

FYI: Please note my answer update. – kriegaex – 2015-11-06T07:54:34.380

how to sudo execute binaries in current directory sudo: ./<some_binary>: command not found. I am using Arch Linux. – Necktwi – 2018-08-04T12:36:30.227

Thank you for the answer. It does solve the problem, but I prefer the solution suggestion in the other two answers as it performs a change only for maven, not for all commands in my PATH. – izomorphius Support Monica – 2014-01-31T09:28:08.870

47

Give sudo your current PATH with:

sudo env "PATH=$PATH" your_command

opyate

Posted 2014-01-31T08:57:41.957

Reputation: 1 454

A great answer, which does not require modifying any settings, letting the caller do everything which is necessary. I would use the -E option in addition, to preserve the rest of the environment. In fact, this is so handy it can be put in a script/alias/function for easy use. I'll add this as a separate answer - but kudos to @opyate! – Tom – 2015-03-31T23:05:07.930

When I try to run this command I get env: cmd: No such file or directory - Any ideas why that would be? – Andy – 2015-04-30T08:47:17.303

2@Andy replace cmd with your actual command. – opyate – 2015-04-30T09:23:39.823

how to sudo execute binaries in current directory sudo: ./<some_binary>: command not found. I am using Arch Linux. – Necktwi – 2018-08-04T12:37:26.313

12

Elaborating on @opyate's answer, I am using the following shell script (which may be named mysudo, for example):

#!/bin/bash
sudo -E env "PATH=$PATH" "$@"
  • -E tells sudo to preserve the environment.
  • env "PATH=$PATH" is expanded outside the sudo call, making the external PATH available inside the sudo too (this is required in addition to the -E as the PATH usually receives special treatment in addition to the treatment the entire environment receives).
  • "$@" passes the arguments our script receives to the sudo line.

Save the script in a file in a directory in the PATH, give it +x permissions, et voilà.

Tom

Posted 2014-01-31T08:57:41.957

Reputation: 221

This is a much better solution for those that don't want to edit any existing files. – qaisjp – 2016-01-29T13:27:15.073

4

Since the current answers are a little vague, the specific setting in /etc/sudoers changing your path is secure_path:

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin

You can modify it it with sudo visudo, or better yet, add the directories you need:

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

mikemaccana

Posted 2014-01-31T08:57:41.957

Reputation: 392

2

I had the same problem when I first installed Maven. The problem got solved after I added the two lines,

export M2_HOME=/tools/noarch/apache-maven-3.1.1
export PATH=$M2_HOME/bin:$PATH

to four files:

/root/.bashrc
/root/.profile

and for the current user (mehran is my Ubuntu username):

/home/mehran/.bashrc
/home/mehran/.profile

Mehran Hatami

Posted 2014-01-31T08:57:41.957

Reputation: 121

1

You must modify root's PATH variable exactly like you did for yourself, i.e. by adding those two lines in sudo's profile, which is located in /root/.bashrc, then source it.

MariusMatutiae

Posted 2014-01-31T08:57:41.957

Reputation: 41 321

1I have edited /root/.bashrc but am not able to source it: sudo source /root/.bashrc gets: sudo: source: command not found and without the sudo I get permission denied(as expected). i believe starting a new terminal should in theory do the same as source, but after starting a new terminal, sudo mvn --version still does not find anything. – izomorphius Support Monica – 2014-01-31T09:20:23.357

@izomorphius You cannot sudo source. You must first switch to sudo with the command sudo su, then you can source the file in question. There is no other way to do it. – MariusMatutiae – 2014-01-31T09:23:34.960