I would like to understand in which cases root can be denied access to a file. I am working on a machine I didn't configure (on my personal laptop I obivously don't have this problem) and I am having this problem which can be boiled down to simply this:

touch test.sh &&\
echo 'echo $PATH' >> test.sh &&\
sudo sh test.sh

will give the error: sh: 0: Can't open test.sh (bash: test.sh: Permission denied with bash).

  • I tried to see if I was under SELinux by running getenforce, but the command was not found.

  • I tried sudo chown root test.sh, but it gives the error: chown: cannot access 'test.sh': Permission denied.

  • Same thing happened when trying to change the ownership of the directory.

I am not necessarily asking for a solution to the overall problem but I want to understand how it's possible that root is denied some access.


On the same machine, if I create a local user (all the above was done as a user logged in via a shared network), all works fine.

  • Can you try sudo sh -c test.sh or simply sudo sh -c 'echo $PATH'? – FedonKadifeli May 20 '19 at 16:47
  • 1
    Specify the path! sudo offers a PATH specifically not including .. sudo sh ./test.sh – waltinator May 20 '19 at 20:00
  • @Rinzwind I am sure the file exists: I just created it with touch. I also see it with ls. However I do see your point from the point of view of sudo, when I do sudo ls I get ls: cannot open directory '.': Permission denied, how could this happen?. On my machine too the 3 lines do what's expected, just not on my professional computer. RE your last point I don't get it: sudo whoami returns root. – Zaccharie Ramzi May 21 '19 at 11:39
  • @FedonKadifeli when doing sudo sh -c test.sh I get sh: 1: test.sh: not found. This is probably linked to what I said in my above comment where sudo ls gives ls: cannot open directory '.': Permission denied. Your second obviously works but I really want to be able to run a file. – Zaccharie Ramzi May 21 '19 at 11:44
  • 1
    Try chmod a+x test.sh – John Ronald May 21 '19 at 15:46

tl;dr if you run

export PATH=.:$PATH # wrong  

then your above mentioned set of commands will ~~work~~ however avoid this solution ... Why ? ... when you run an executable giving it either a full path


or relative path

./../cool/binary # notice this begins with a ./  period slash

you directly control where the executable is coming from ... however if by mistake or by some rogue process your env var PATH gets updated with a prepend of a dir(s) which contains (wrong or malicious) executables with matching names

export PATH=/wrong/dir:/hackers/own/dir:$PATH

and you just use

myexecutable_name  # using naked binary name

you could be running


when you intended to run


which is why production code or anything run as root should explicitly spell out where the binary is coming from

Now going back to your original question ... your code assumes PATH includes current dir '.' which it should not contain for prod ids or root

export PATH=.:$PATH # wrong - bad for root or prod id yet handy for dev folks

instead execute using full path ... problem is you want to avoid possibility of running wrong binary which happens to be in your current dir when you intended to run binary from the standard dir as defined in your PATH

Not convinced ? spend some quality time with critical infrastructure code especially which is at an intersection between responsibilities ... where team B binary is executing a binary from team A and you will always see full path used ... another inspiration is to beef up on namespace conflicts

| improve this answer | |

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.