217

I have a script called foo.sh in my home folder.

When I navigate to this folder, and enter ./foo.sh, I get

-bash: ./foo.sh: Permission denied.

When I use sudo ./foo.sh, I get

sudo: foo.sh: command not found.

Why does this happen and how I can fix it?

Rob Kielty
  • 7,958
  • 8
  • 39
  • 51
Neko
  • 3,550
  • 7
  • 28
  • 34

11 Answers11

204

Permission denied

In order to run a script the file must have an executable permission bit set.

In order to fully understand Linux file permissions you can study the documentation for the chmod command. chmod, an abbreviation of change mode, is the command that is used to change the permission settings of a file.

To read the chmod documentation for your local system , run man chmod or info chmod from the command line. Once read and understood you should be able to understand the output of running ...

ls -l foo.sh

... which will list the READ, WRITE and EXECUTE permissions for the file owner, the group owner and everyone else who is not the file owner or a member of the group to which the file belongs (that last permission group is sometimes referred to as "world" or "other")

Here's a summary of how to troubleshoot the Permission Denied error in your case.

$ ls -l foo.sh                    # Check file permissions of foo
-rw-r--r-- 1 rkielty users 0 2012-10-21 14:47 foo.sh 
    ^^^ 
 ^^^ | ^^^   ^^^^^^^ ^^^^^
  |  |  |       |       | 
Owner| World    |       |
     |          |    Name of
   Group        |     Group
             Name of 
              Owner 

Owner has read and write access rw but the - indicates that the executable permission is missing

The chmod command fixes that. (Group and other only have read permission set on the file, they cannot write to it or execute it)

$ chmod +x foo.sh               # The owner can set the executable permission on foo.sh
$ ls -l foo.sh                  # Now we see an x after the rw 
-rwxr-xr-x 1 rkielty users 0 2012-10-21 14:47 foo.sh
   ^  ^  ^

foo.sh is now executable as far as Linux is concerned.

Using sudo results in Command not found

When you run a command using sudo you are effectively running it as the superuser or root.

The reason that the root user is not finding your command is likely that the PATH environment variable for root does not include the directory where foo.sh is located. Hence the command is not found.

The PATH environment variable contains a list of directories which are searched for commands. Each user sets their own PATH variable according to their needs. To see what it is set to run

env | grep ^PATH

Here's some sample output of running the above env command first as an ordinary user and then as the root user using sudo

rkielty@rkielty-laptop:~$ env | grep ^PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

rkielty@rkielty-laptop:~$ sudo env | grep ^PATH
[sudo] password for rkielty: 
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin

Note that, although similar, in this case the directories contained in the PATH the non-privileged user (rkielty) and the super user are not the same.

The directory where foo.sh resides is not present in the PATH variable of the root user, hence the command not found error.

Rob Kielty
  • 7,958
  • 8
  • 39
  • 51
  • Weird that `sudo $PWD/temp.sh` doesn't work neither, while `sudo echo $PWD` shows just what I waited for. (Mac) – Nakilon Oct 01 '13 at 17:03
  • 1
    @Nakilon if you put that in a question with full details I should be able to troubleshoot it for you further. The issue is likely which shell (your first command shell or the shell launched by sudo) has evaluated $PWD – Rob Kielty Oct 01 '13 at 21:33
  • @RobKielty, never mind. I don't remember the exact issue, but probably it was smth like not setting chmod -x for one command in script, and calling script via sudo generated not so understandable error msg. – Nakilon Oct 03 '13 at 01:33
  • 26
    @Rob: so how does one make `sudo`'s `PATH` the same as the user's? – Tom Mar 31 '15 at 21:16
  • @Tom this is a good question, not sure I can answer it in a comment as I would need some context so as to best advise you. But as a starting point I would suggest you review the sudo documentation in full (which is very good) my instinct would be to NOT make the path for root the same as a general user but that instinct is based on running a machine a production environment versus say a private laptop. – Rob Kielty Apr 01 '15 at 13:05
  • 1
    @Rob: I have found a way in the meantime (see my answer below). – Tom Apr 01 '15 at 20:54
  • I had this problem with `sudo asterisk -r`, which didn't work. Asterisk is located in `/usr/sbin`, and this was in the root PATH, but not in my user PATH. After adding `/usr/sbin` to my user PATH, it worked. You say "the PATH environment variable for root does not include the directory where foo.sh is located", so you say I should add the path to the root PATH, which is contrary to my findings. – SPRBRN Mar 24 '16 at 09:57
  • `sudo`'s `"command not found"` has nothing to do with the PATH; if you set the execute permissions, then `sudo` executes it! It's just some quirk in sudo (that should arguably be fixed; error messages should not be gratuitously inaccurate). – Kaz Jan 22 '19 at 00:52
  • 1
    @Tom you can change the secure_path in /etc/sudoers – DennisLi Jul 20 '19 at 03:45
  • _“The reason that the root user is not finding your command is likely that the `PATH` environment variable for root does not include the directory where `foo.sh` is located.”_ — What? Why do I have to manipulate `PATH`? Why doesn’t `sudo ./foo.sh` get interpreted as `sudo "$(pwd)/foo.sh"`? When running `sudo` in a script, why do I have to write something like `sudo "$(pwd)/$(basename "${BASH_SOURCE[0]}")"` instead of `sudo "${BASH_SOURCE[0]}"`? – Sebastian Simon Aug 27 '20 at 03:22
  • Hi @Philip Rego I'm assuming some knowledge of the purpose of sudo. Do u mean with and without sudo? – Rob Kielty Aug 30 '21 at 18:57
  • 1
    I'm wondering why the PATH variable has a different value when I run as sudo compared to my regular user. I set PATH in `/etc/environment` but this PATH is not used when ran as sudo. Where do I set the PATH for use in sudo? – Philip Rego Aug 30 '21 at 21:52
  • It should be configured in the shell used by root or possibly via sudo configuration. Review the man pages for each for details. The PATH configured for root is typically limited to a short list of directories so as to prevent user programs from being run by root accidentally and to force the root user to explicitily reference the program name that it is to invoke. This would be seen as good practise from a security point of view. But of course PATH restriction is the tip of the iceberg when it comes to Linux security. – Rob Kielty Sep 01 '21 at 08:45
167

The other solutions I've seen here so far are based on some system definitions, but it's in fact possible to have sudo use the current PATH (with the env command) and/or the rest of the environment (with the -E option) just by invoking it right:

sudo -E env "PATH=$PATH" <command> [arguments]

In fact, one can make an alias out of it:

alias mysudo='sudo -E env "PATH=$PATH"'

(It's also possible to name the alias itself sudo, replacing the original sudo.)

Tom
  • 4,910
  • 5
  • 33
  • 48
33

Check for secure_path on sudo

[root@host ~]# sudo -V | grep 'Value to override'
Value to override user's $PATH with: /sbin:/bin:/usr/sbin:/usr/bin

If $PATH is being overridden use visudo and edit /etc/sudoers

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
codemonkee
  • 2,881
  • 1
  • 25
  • 32
  • Thanks! That helped to solve a mystery of sudo not being able to run commands. – Evgeny Goldin May 06 '14 at 12:27
  • You don't explain why they're different in the first place. – Philip Rego Aug 29 '21 at 02:03
  • @PhilipRego - These answers are +6 years old, If you don't feel there is enough details on multiple answers... Try offering some suggestions on what you are looking for, or better still edit the answer to provide the details you find lacking. – codemonkee Aug 30 '21 at 16:51
  • sudo -V | grep 'Value to override', comes out empty in Ubuntu 20.04 – Hem Aug 04 '22 at 20:42
  • I don't use Ubuntu @Hem. Perhaps the output is different when looking at `sudo -V` and the `grep` isn't capturing the same text. In any case, Review the Manual for Ubunto and Sudoers and see how `secure_path` and other aspects are applied. - https://manpages.ubuntu.com/manpages/focal/man5/sudoers.5.html – codemonkee Aug 16 '22 at 00:32
7
  1. Check that you have execute permission on the script. i.e. chmod +x foo.sh
  2. Check that the first line of that script is #!/bin/sh or some such.
  3. For sudo you are in the wrong directory. check with sudo pwd
Ed Heal
  • 59,252
  • 17
  • 87
  • 127
6

You can also create a soft link to your script in one of the directories (/usr/local/bin for example) in the super user PATH. It'll then be available to the sudo.

chmod +x foo.sh
sudo ln -s path-to-foo.sh /usr/local/bin/foo

Have a look at this answer to have an idea of which directory to put soft link in.

Rob Kielty
  • 7,958
  • 8
  • 39
  • 51
TrigonaMinima
  • 1,828
  • 1
  • 23
  • 35
2

It seems that linux will say "command not found" even if you explicitly give the path to the file.

[veeam@jsandbox ~]$ sudo /tmp/uid.sh;echo $?
sudo: /tmp/uid.sh: command not found
1
[veeam@jsandbox ~]$ chmod +x /tmp/uid.sh
[veeam@jsandbox ~]$ sudo /tmp/uid.sh;echo $?
0

It's a somewhat misleading error, however it's probably technically correct. A file is not a command until its executable, and so cannot be found.

Jeff MacDonald
  • 457
  • 4
  • 3
2

Try chmod u+x foo.sh instead of chmod +x foo.sh if you have trouble with the guides above. This worked for me when the other solutions did not.

Peter David Carter
  • 2,548
  • 8
  • 25
  • 44
1

Regarding "command not found" when using sudo far less hackier way would be to edit secure_path.

It is perfectly described here: https://superuser.com/questions/927512/how-to-set-path-for-sudo-commands

Do-do-new
  • 794
  • 8
  • 15
0

Ok this is my solution: in ~/.bash_aliases just add the following:

# ADDS MY PATH WHEN SET AS ROOT
if [ $(id -u) = "0" ]; then
   export PATH=$PATH:/home/your_user/bin 
fi

Voila! Now you can execute your own scripts with sudo or set as ROOT without having to do an export PATH=$PATH:/home/your_user/bin everytime.

Notice that I need to be explicit when adding my PATH since HOME for superuser is /root

-1

If you are not so comfortable with the command line and are using Ubuntu you can solve the problem as follows:

  1. Open the folder window where the file is located
  2. Right click on the executable file and choose Properties
  3. Go to the Permissions tab and highlight Allow executing file as program

enter image description here

With this solution you allow the user to execute the file as a program and you don't need sudo (or change the PATH environment variable for root).

Ricoter
  • 665
  • 5
  • 17
-5

It seems sudo command not found

to check whether the sudo package is installed on your system, type sudo , and press Enter . If you have sudo installed the system will display a short help message, otherwise you will see something like sudo: command not found

To install sudo, run one of the following commands using root account:

apt-get install sudo # If your system based on apt package manager

yum install sudo # If your system based on yum package manager

Khaled Eid
  • 54
  • 5
  • 1
    This doesn't answer the question since the issue was the set executable bit not being set on the script. – ewokx Sep 16 '20 at 01:49
  • It's not the sudo command that wasn't found. The output means that is sudo "saying" that the "foo.sh" command wasn't found. – Waldir Leoncio Nov 04 '20 at 11:04