Shell – Why is the program called “set” not being executed

pathshellshell-builtin

I've created a simple C program like so:

int main(int argc, char *argv[]) {

    if (argc != 5) {
       fputs("Not enough arguments!\n", stderr);
       exit(EXIT_FAILURE);
    }

And I have my PATH modified in etc/bash.bashrc like so:

PATH=.:$PATH

I've saved this program as set.c and am compiling it with

gcc -o set set.c

in the folder

~/Programming/so

However, when I call

set 2 3

nothing happens. There is no text that appears.

Calling

./set 2 3

gives the expected result

I've never had a problem with PATH before and

which set

returns ./set. So it seems the PATH is the correct one. What's is happening?

Best Answer

Instead of using which, which doesn't work when you need it most, use type to determine what will run when you type a command:

$ which set
./set
$ type set
set is a shell builtin

The shell always looks for builtins before searching the $PATH, so setting $PATH doesn't help here.

It would be best to rename your executable to something else, but if your assignment requires the program to be named set, you can use a shell function:

$ function set { ./set; }
$ type set
set is a function
set ()
{
    ./set
}

(That works in bash, but other shells like ksh may not allow it. See mikeserv's answer for a more portable solution.)

Now typing set will run the function named "set", which executes ./set. GNU bash looks for functions before looking for builtins, and it looks for builtins before searching the $PATH. The section named "COMMAND EXECUTION" in the bash man page gives more information on this.

See also the documentation on builtin and command: help builtin and help command.

Related Question