2

I'm trying to remove a single executable from $PATH, without modifying it

e.g I have /Users/USER/Library/Python/2.7/bin/ in $PATH, and I'd like to exclude services.py from that directory.

I know chmod -x services.py will work, but I'm trying to find a better way

Is it possible?

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
daisy
  • 54,555

1 Answers1

4

If you can move the file to a sub-directory that will avoid its execution.
If you can not, there are some workarounds:

You can add something of a higher priority so that it executes before the executable you are trying to avoid.

New dir in PATH.

You can create an executable at a higher level in the PATH order.

If $PATH is /usr/local/bin:/usr/bin:/bin, an (empty?) executable at /usr/bin will be executed at a higher priority than an executable at /bin.

In this direction, you can add a path at the start of $PATH to ensure that the new executable is executed before (in replacement of) services.py

Note that some shells remember executed path of programs. In bash that is controlled by the command hash (a hash -r will remove all hashed programs). A new bash shell has no hashed programs, except those executed in the starting files (usually ~/.bashrc and/or ~/.profile). So, a new shell which has the new PATH in effect at the start will work.

If you can not change the PATH, or move the file, you can you can use a function or alias definition in ~/.bashrc, or some other start up file like ~/.profile.

Functions and aliases have higher precedence than executables, so, naming a function (or alias) like the executable will effectively replace it in shells that have such function defined.

function

Something as simple as this will do:

services.py(){ :; } # do nothing

To test, you may set ls to nothing:

ls(){ :; }

A function could be erased with unset -f FunctionName.

 $ unset -f ls

To remove the ls function.

Note that a function is not perfect, the original executable could be called with the full path:

$ /bin/ls
listOfFiles
…

A function will prevent just "this shell" from executing the program. Any other shell (or program that could call execve by itself) will run the executable.

alias

An alias is less powerful, it only replace the first word of a simple command.
And if the command has some form of quoting, it will avoid the alias.

$ alias ls='echo "none"'
$ ls
none
$ \ls
ListOfFiles
…

An alias could be erased with unalias AliasName. So, this:

 $ unalias ls

Will remove the alias definition of ls.

The most robust method to change the PATH. Either by pre-pending a new dir or by moving the file to a new directory. Include such directory in the $PATH only for those instances that will be allowed to execute the program.