The main difference between aliases and functions is that aliases don't take arguments¹, but functions do. When you write something like
alias l='ls --color',
l foo is expanded to
ls --color foo; you can't grab
foo into the alias expansion and do something different with it the way you can do with a function. See also How to pass parameter to alias?.
Aliases are looked up before functions: if you have both a function and an alias called
foo invokes the alias. (If the alias
foo is being expanded, it's temporarily blocked, which makes things like
alias ls='ls --color' work. Also, you can bypass an alias at any time by running
\foo.) I wouldn't expect to see a measurable performance difference though.
Functions and standalone scripts have mostly similar capabilities; here are a few differences I can think of:
- A function runs inside the shell environment; a script runs in a separate process. Therefore a function can change the shell environment: define environment variables, change the current directory, etc. A standalone script can't do that.
- A function must be written in the language of the shell you want to use it in. A script can be written in any language.
- Functions are loaded when they are defined. Scripts are loaded each time they are invoked. This has several consequences:
- If you modify a script, you get the new version the next time you invoke it. If you change a function's definition, you have to reload the definition.
- Functions are faster on heavily loaded systems.
- If you have a lot of functions that you may not use, they'll take up memory. Ksh and zsh, but I think not bash, have a form of function autoloading.
Something that's intermediate between a function and a standalone script is a script snippet that you read with the
. builtin. Like a function, it can modify the shell's environment, and must be written in the shell's language. Like a script, it is loaded each time it's invoked and no sooner.
Yeah, I know, this doesn't apply to tcsh.