9

The last line of my .bash_profile is:

alias cp=/usr/local/bin/gcp

However that is being squashed by the entry in my $PATH :

$which cp
/bin/cp
11:54:32/OCspark $type cp
cp is aliased to `/usr/local/bin/gcp'

I had thought that aliases override the PATH .. ?

  • 1
    For the record: technically, aliases do not override any values in the PATH envar. – can-ned_food Aug 30 '17 at 13:57
  • Obligatory caution: In general, it is not good practice to rename common commands. This can bite you two ways. 1) If you work on another system and use your command by habit, you will get the unexpected behavior of the native command. 2) If anyone else uses your system, even to advise/help you solve a problem, they will get the unexpected behavior of your customization. Custom commands are fine, just don't name them the same as common existing ones. – Joe Sep 5 '17 at 10:24
  • @joe Actually it is more of the reverse here: the os/x version of cp lacks options from nix so it does not behave as expected (except to those who *like the hobbled mac version) – javadba Sep 5 '17 at 15:44
21

The which command returns only executables: it knows nothing about aliases, since it is an external program, and there is no mechanism for passing alias information to a child process.

If you enter the command type -a cp you will see all possible interpretations, in order of preference. This includes any alias, since type is a bash internal command.

It is important to realise that an alias will not be interpreted by a sub-process, such as a script or an interactive editor which has an option to run system commands.

If you make cp a function, then your version will run in scripts, though not from other programs:

cp() { /usr/local/bin/gcp "$@"; }

If you want your cp to work everywhere, add $HOME/bin at the head of your PATH list and point $HOME/bin/cp to point to it:

ln -s /usr/local/bin/gcp $HOME/bin/cp

This makes a symbolic link, though you can make it a slightly more efficient hard link (omit -s), but this will normally need root permissions (sudo ln ...). Creating a function and adding to the PATH variable will be done in one of the bash start-up scripts, with user permissions.

| improve this answer | |
  • 1
    Although on CentOS (and AIUI all RedHat) the standard profile (unless overridden) creates an alias for which that runs /usr/bin/which with input piped from the output of alias and an option that tells it to read that input and use it to show an alias if it matches the command. See unix.stackexchange.com/questions/10525/… – dave_thompson_085 Aug 30 '17 at 2:09
  • @dave_thompson_085 - Interesting comment: I've not used those distributions. I use Ubuntu and I can get much the same effect by simply aliasing which to type. Then which -a operates like the external program, with the addition of the alias and function definitions. In general I don't alias which=type, because I like to use $(which ProgName) when I want to force the use of an external program, bypassing any alias or function definitions. – AFH Aug 30 '17 at 10:28
  • 1
    Hard links can't cross filesystems, so the non-symbolic ln suggestion will only work if your home directory is on the same filesystem as /usr/local/bin. It will also behave oddly if you update gcp, as your hard link will probably still refer to the old version. – Useless Aug 30 '17 at 12:30
  • @Useless - Valid points, which is part of why I edited my answer to suggest a symbolic link first, though I think that the permissions are probably the most important consideration. As for updating gcp, it will depend whether the update is done by opening and writing or by deleting and re-creating. Note that it is immaterial whether an absolute or relative source path is used to create a hard link, while a symbolic link usually needs an absolute path. Links are used extensively in the OS, and they are mostly symbolic. – AFH Aug 30 '17 at 12:47
  • 1
    @can-ned_food - It's not as simple as setting it in the current shell: it has to be set in each script, together with importing the aliases. – AFH Aug 30 '17 at 18:33
13

Aliases are internal to the shell. Other programs won't know about them.

which is not a Bash builtin (it is a builtin in some other shells, e.g. zsh). Since which has no privileged information into Bash's aliases, which just looks through PATH for the given term.

type, on the other hand is a Bash builtin, so it can report on aliases.

| improve this answer | |
  • 2
    And, also, aliases are only expanded if the first word in a command. Maybe that isn't relevant. – can-ned_food Aug 30 '17 at 13:53

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.