In the previous posts we talked about which files you could use to customize your bash
environment.
There are (mainly) three customizations you can perform:
This post will look at some useful aliases and functions.
bash
aliases
Note: bash
aliases are something completely different from Finder aliases. The closest shell equivalent for Finder alias files are symbolic links.
bash
aliases are basically text substitutions. For example a common alias
is to define:
alias ll="ls -l"
You can type this alias
definition directly into bash
but then the definition will only exist for that particular shell. When you open a new terminal window it will know nothing of this alias. If you want an alias to exist in all your shells (and usually you do), you need to add the above line to your .bash_profile
or .bashrc
. (Learn about the difference here.)
Whenever you modify the .bash_profile
or .bashrc
it will not automatically be loaded into any shell that is already open, you either have to close the Terminal window and open a new one or write
$ source ~/.bash_profile
(or ~/.bashrc
) to load the new settings.
Once you have set the alias, anytime you type ll
at the start of a command, bash
will replace it with ls -l
before executing. Since subsequent arguments are left alone they will just be picked up by the substituted ls
command, so if you type ll -a
bash will substitute that to ls -l -a
and it will work just your would expect.
You can make the alias
more complex if you want:
alias lll="ls -alhTOe@"
If you always want to use the long format of ls
, you can alias the ls
command itself:
alias ls="ls -l"
Then, when ever you type ls
it will be replaced with ls -l
. Note the lack of spaces around the ‘=
’, as usual when assigning values in bash.
Uncovering the alias
You can unset or delete an alias with the unalias
command:
$ unalias ls
This will return to the default ls
command (for this bash instance only).
Since alias substitution only happens at the beginning of the command, you can also bypass it once by starting the command line with a different character:
$ "ls" -S
$ \ls -S
Either way of typing this will use the original ls
command, avoiding substitution, just this once.
If you are unsure if a command has an alias or want to know what gets substituted, then you can have the alias definition printed with
$ alias ls
alias ls='ls -l'
$ alias lll
alias lll='ls -alhTOe@'
You can also list all defined aliases by running alias
without any arguments:
$ alias
alias ll='ls -l'
alias lll='ls -alhTOe@'
alias ls='ls -l'
Some Alias examples
Some users like to alias the potentially dangerous commands rm
, mv
and cp
with the -i
option, which forces the user to confirm when a file is going to be deleted or overwritten:
alias rm="rm -i"
alias mv="mv -i"
alias cp="cp -i"
Then if you do something that could destroy an existing file you will be prompted to confirm:
$ rm my_important_file
remove my_important_file?
You can still use \rm
to bypass the alias, if you believe you know what you are doing and want to avoid being prompted several times.
You can add short cuts to cd
to parent folders:
alias ..="cd .."
alias ...="cd ../.."
alias cd..="cd .."
Since alias substitution only takes place at the beginning of the command, you can still use ..
normally as an argument.
Note that the last alias cd..
is a substitution of a common typo. Since the output of the alias is not checked for further alias substitutions you cannot use alias cd..=..
to define it using the previous alias. Each alias must stand for itself.
You can also use aliases to make complex or hard to memorize commands easier to remember:
alias badge="tput bel"
The first command will play a system alert and set a ‘badge’ on the terminal application if it is in the background. This is useful to get notified of long running commands:
$ hdiutil convert image.sparseimage -format UDZO image.dmg; badge;
The substitution can be long and multiple commands can be separated by ;
alias dockspace="defaults write com.apple.dock persistent-apps -array-add '{\"tile-type\"=\"spacer-tile\";}'; killall Dock;"
The dockspace
alias uses this hack to add a spacer item to the dock.
We have seen earlier with the ll
alias that any text or arguments after the alias will just be added to the substituted command. We can use this to our advantage:
alias reveal='open -R'
alias xcode='open -a Xcode'
alias pacifist='open -a Pacifist'
All of these commands will require a file path as an ‘argument’ to work properly.
Functions: beyond the alias
While bash aliases are useful and easy to define, they have limitations. Aliases will only be replaced at the beginning of the command prompt. Also additional arguments will be appended after the replacement. If you need to insert additional arguments somewhere in the replacement, you cannot achieve that with aliases.
For example, to display the man page for ls
in the Preview application you need the following commands:
$ man -t ls | open -f -a "Preview"
If you wanted to alias this you would have to insert the arguments after man -t
and before the pipe. Since aliases, only substitute the beginning of the command, this will not work. we need to define a bash function:
function preman() {
man -t $@ | open -f -a "Preview"
}
Sometimes you will see bash functions defined without the function
keyword, but I prefer to use it since it makes the code more readable.
The $@
will be replaced with all the arguments passed into the function, so when use the function
$ preman ls
the argument ls
will be substituted where the $@
is.
You can also use the positional argument variables $1
, $2
, etc:
function recipe-open() {
open "$(autopkg info '$1' | grep 'Recipe file path' | cut -c 22-)"
}
Within functions the full power of bash
scripting is at your service. You can even call other scripting languages.
# prints the path of the front Finder window. Desktop if no window open
function pwdf () {
osascript <<EOS
tell application "Finder"
if (count of Finder windows) is 0 then
set dir to (desktop as alias)
else
set dir to ((target of Finder window 1) as alias)
end if
return POSIX path of dir
end tell
EOS
}
# changes directory to frontmost
alias cdf='pwdf; cd "$(pwdf)"'
The last alias cdf
has to be defined as an alias. Since a function or script could not change the directory for the current shell, you have to use alias substitution to get the cd
.
In general functions (and scripts) are more powerful and versatile than aliases, but aliases provide and easy and comparatively safe way to customize the your shell environment.
Putting it all together
Here is a sample .bash_profile
with many of the examples given here and in the previous article. You can use this as a starting point for your own bash configuration.