8

I was playing around a bit with the names of some executables, putting them in a folder, ~/bin, which is in my $PATH. Now I'm wondering how I can set the preferences of a bash-3.2 terminal so that it picks up these executables instead of the builtins or aliases to execute.

For example, if I put a script named cd in a directory in $PATH, the builtin for cd is still executed. However, if I create an alias for cd, then this alias will be executed, overriding the builtin.

$ type cd
cd is a shell builtin

My questions

  1. Is there a way to make an executable file in $PATH have, by default, preference over a shell builtin, by executing only, e.g. cd without having to resort to using the commands builtin or command?

  2. I'm also interested in any official reference which discusses this preference (not the reasoning, that I do understand).

Note: This question is purely for personal educational purposes, I am wondering why it works the way it works.

Bernhard
  • 12,272
  • To the close voters: Note that this is in my opinion NOT a duplicate, because I am specifically not looking for command answers. – Bernhard Feb 14 '14 at 13:27
  • @slm Well, there is only three close votes, and you can always retract it afaik. But I also updated the title. – Bernhard Feb 14 '14 at 13:35
  • I'm saving the vote for after it gets closed to reopen, that's generally how it goes (it's @ 4 now). – slm Feb 14 '14 at 13:51
  • Seems like a better title would've been "How do I override Bash from using builtins, and always search the $PATH?". That sep. you from the other Q, then inside the body you can expand what you're asking. – slm Feb 14 '14 at 13:54
  • 1
    I hope you don't mind I attempted to edit it. Feel free to revert but I think you actually have a good Q, it just needed to be polished a bit. Any thoughts on changing the title? I'll start the reopen now. – slm Feb 14 '14 at 14:04
  • Aren't you just looking for aliases? I mean alias cd=/bin/cd will override the cd builtin. – terdon Feb 14 '14 at 14:26
  • @terdon I think that might answer the question as it is stated, but it is not really what I am looking for from an educational perspective. The enable in the answer is more the answer that I intended. – Bernhard Feb 14 '14 at 14:32

2 Answers2

5

My question is, is there a way to make an executable file in $PATH have preference over an shell builtin, by executing only, e.g. cd without builtin or command?

You can use the builtin enable to disable/enable a builtin. Say:

enable -n cd

to disable the builtin cd. Say enable cd to enable the builtin.

The following would give an example of switching between the builtin and command:

$ type cd
cd is a shell builtin
$ enable -n cd
$ type cd
-bash: type: cd: not found
$ enable cd
$ type kill
kill is a shell builtin
$ enable -n kill
$ type kill
kill is /bin/kill
$ enable kill
$ type kill
kill is a shell builtin
devnull
  • 10,691
2

Disable "commands" one at a time

You can use the commands command and builtin to call out one or the other.

$ command cd

Will disregard any builtins by that name and search the $PATH. The opposite command to this which will only use a builtin is builtin.

$ builtin cd

Disable builtins

$ help enable
enable: enable [-a] [-dnps] [-f filename] [name ...]
    Enable and disable shell builtins.

    Enables and disables builtin shell commands.  Disabling allows you to
    execute a disk command which has the same name as a shell builtin
    without using a full pathname.

    Options:
      -a    print a list of builtins showing whether or not each is enabled
      -n    disable each NAME or display a list of disabled builtins
      -p    print the list of builtins in a reusable format
      -s    print only the names of Posix `special' builtins

    Options controlling dynamic loading:
      -f    Load builtin NAME from shared object FILENAME
      -d    Remove a builtin loaded with -f

    Without options, each NAME is enabled.

    To use the `test' found in $PATH instead of the shell builtin
    version, type `enable -n test'.

    Exit Status:
    Returns success unless NAME is not a shell builtin or an error occurs.

Example

$ type cd
cd is a shell builtin
$ enable -n cd
$ type cd
cd is /usr/bin/cd

$ enable cd
$ type cd
cd is a shell builtin
slm
  • 369,824
  • In my opinion this is not an answer to my question, because I want to specifically know whether I can change or not, somehow, the default behavior of cd, without command or builtin – Bernhard Feb 14 '14 at 13:12
  • In its current form it answer what you wrote. Perhaps you should refine your Q then? – slm Feb 14 '14 at 13:14
  • 2
    No, because command cd would only "Runs COMMAND with ARGS ignoring shell functions.Runs COMMAND with ARGS ignoring shell functions.", so command cd will still call the builtin cd. Anyhow, I did update the question. – Bernhard Feb 14 '14 at 13:18
  • Note that I am using bash. For zsh command seems to do that indeed. – Bernhard Feb 14 '14 at 13:23