Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm confused about execute file permissions not behaving as I expect. Probably because my expectations are wrong. Anyway:

I have a script file, for simplicity is just called s, located in ~/bin. For the sake of this example, the file contains just the following lines:

#!/bin/zsh
echo "Test";

Very simple.

I navigate to the ~/bin directory, and chmod the file permissions of s to 400 - i.e., read-only for me only. No execute permission. So then I try executing the script by entering its path, giving this:

% ./s
zsh: permission denied: ./s

So far so good. The file can't be executed due to the wrong permissions. Bumping permissions up to 500 (execute permission granted) works fine too - with these permissions, the file executes fine:

% ./s
Test

This is all as expected. But then I chmod permissions back down to 400 (execute permission off again), try sourceing the file, and this happens:

% source s
Test

Although permissions are 400, the script executes.

So here's my question: why does ./s fail (like it should) but source s executes normally? Doesn't this defeat the whole purpose of the execute permission?

At 400 permissions, sh s and zsh s also work.

I'm sure I'm either doing or understanding something horribly wrong somewhere. Can someone point out where to me, and explain the difference between ./s, source s, sh s and zsh s?

share|improve this question
add comment

1 Answer

up vote 6 down vote accepted

When you run ./s, you tell the kernel to execute the program s. If you have execution permission, then the kernel reads the first few bytes of the file, sees the #! line so it knows that this is a script, and runs the interpreter, passing it the script name as its first argument. If you don't have execute permission, the kernel aborts the execution at the first step.

When you run zsh s, you execute zsh, and tell it to read the file called s and interpret it as commands. You aren't executing s, you're executing zsh. Same thing with sh s or cat s.

When you run source s, again, you tell zsh to read a file, so what matters is that you have read permission on it.

share|improve this answer
    
Okay, that makes sense. But doesn't that completely defeat the point of having the execute permission? Doesn't matter if it's set or not, I'll always be able to execute the script (or tell zsh to interpret the commands in the script, which is equivalent). –  C106 Aug 31 '12 at 9:09
    
Also, cat s just prints the contents of the file. cat s | zsh passes them to zsh and prints Test. –  C106 Aug 31 '12 at 9:11
1  
@C106 The point of the execute permission is to indicate that the file represents something that you can execute without additional information. It's also important if the file is setuid/setgid. A file might not have execution permission but nonetheless consist of instructions that it happens that some computer program somewhere executes. –  Gilles Aug 31 '12 at 20:32
    
That makes a lot of sense, and is in fact incredibly obvious really. Thanks. –  C106 Sep 1 '12 at 0:07
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.