Consider the following command:
$ /Applications/MailSteward.app/Contents/MacOS//MailSteward 1 >& /dev/null
That’s the command for MailSteward to update it’s database with email received since it was last updated. It’s also a bitch of a command to remember. When faced with an unwieldy command, you basically have four alternatives:
- Memorize the command and type the thing in over and over; or
- Create a shell script; or
- Use an alias; or
- Use the
(Okay, I know. I know. There are other alternatives.)
Typing the thing in over and over is ridiculous. Creating shell scripts is a viable solution but, in the long run, you end up with too many shell scripts. Aliases could work (and we’ll get to them shortly) but suffer from the same shortcoming as shell scripts. The history command is a perfect solution.
history is a built-in shell command and it’s availability depends on the shell you’re running. The default OS X shell is Bash which includes a
As you enter commands from the command line, Bash caches them and, once you close the terminal or logout, it appends them to a file in your home directory called .bash_history. This file reflects the most recent 500 commands by default. You can change this number via the HISTSIZE environment variable, but for most people 500 is more than enough. .bash_history is just a simple text file.
$ cat ~/.bash_history
Interesting but not particularly useful. Now lets try the
2 ls -ald b*
Depending on how often you use the terminal, your list may be long or short. As you can see, mine has 500 entries. That’s a lot of data to sift through. How do we find something specific? How do we find that MailSteward command we entered yesterday? By piping the output through
$ history | grep MailSteward 42 /Applications/MailSteward.app/Contents/MacOS/MailSteward 1 >& /dev/null 132 /Applications/MailSteward.app/Contents/MacOS/MailSteward 1 >& /dev/null 365 /Applications/MailSteward.app/Contents/MacOS/MailSteward 1 >& /dev/null 469 /Applications/MailSteward.app/Contents/MacOS/MailSteward 1 >& /dev/null
Now that we’ve found the command we want, what do we do with it? Those numbers seem irrelevant. Who cares that the MailSteward command is the 42nd or 132nd or 365th command in our history file? We do because we can use those numbers to execute the command.
$ !42 /Applications/MailSteward.app/Contents/MacOS/MailSteward 1 >& /dev/null $
That’s exclamation mark (!) four (4) two (2). The exclamation mark is more commonly called bang. !42 tells Bash to execute entry 42 from the history file. Once we hit enter, Bash displays and runs our command. So our workflow would look like this:
$ history | grep MailSteward 42 /Applications/MailSteward.app/Contents/MacOS/MailSteward 1 >& /dev/null 132 /Applications/MailSteward.app/Contents/MacOS/MailSteward 1 >& /dev/null 365 /Applications/MailSteward.app/Contents/MacOS/MailSteward 1 >& /dev/null 469 /Applications/MailSteward.app/Contents/MacOS/MailSteward 1 >& /dev/null $ !42 /Applications/MailSteward.app/Contents/MacOS/MailSteward 1 >& /dev/null $
|Pretty sweet stuff, but do you really want to type *history||grep MailSteward* every time you need to find that command? Of course not. So let’s talk about the
Like the history command,
alias is a built-in shell command and is available in Bash.
alias is used to create short-cuts or command abbreviations. Consider the following:
$ ll -bash: ll: command not found
That’s lower-case-el (l) lower-case-el (l). It’s not found because it’s not a valid command.
$ alias ll=’ls -al’ $ ll drwxr-xr-x+ 36 stephen staff 1224 Mar 2 15:23 . drwxr-xr-x 5 root admin 170 Oct 25 22:38 .. -rw-r–r–@ 1 stephen staff 24580 Mar 2 10:06 .DS_Store -rwx—— 27 stephen staff 918 Mar 1 11:46 bang-goes-boom.txt -rw——- 1 stephen staff 3 Oct 25 22:38 omg-a-file.txt
Look at that. We’ve used
alias to create our own custom command.
ll now executes
ls lists directory contents. Here’s the breakdown of the parameters:
-a Include directory entries whose names begin with a dot (.). -G Enable colorized output. -l (The lowercase letter ‘el’.) List in long format.
So now you can use
ls for regular directory listings and
ll for long listings. Nice.
One quick word of warning: Be careful what you choose as an alias. Check this out:
Now every time we enter
ls the system is going to execute
ssh, which is probably not what we want. The
ls command is important. Pick your alias carefully. (If you accidentally do this, you can bypass the alias and get to the real
ls command by entering its full path: /bin/ls. See
man which for information on locating a command’s full path. Or you can simply enter alias ls=’ls’ to undo it.)
Okay, where were we?
Unfortunately, aliases are forgotten as soon as you logout. So every time you login, you have to redefine your
ll alias. Bummer. Especially if you have several. What we need is a file that gets executed every time we login and defines all our aliases. Maybe a file called aliases.
And we can do that.
Every time you open a terminal window in OS X, a file called ~/.profile gets executed. The thing is, this file may or may not exist. Open your terminal (Utilities -> Terminal) and enter the following:
$ cat $HOME/.profile
If it doesn’t exist, don’t sweat it because you can create it. The point is this: All we need is .profile to execute our aliases file and we’re good to go.
If ~/.profile does not exist, do this:
$ touch $HOME/.profile
Now, using your favorite text editor, edit .profile and add the following:
That’s dot (.) space ( ) tilde (~) slash (/).
The dot (.) space ( ) is shorthand for source or execute this file as though it was a Bash script. So we’re telling .profile to execute ~/aliases as though it was a Bash script. Awesome.
Now we just need to create our ~/aliases file. Using your favorite text editor, create ~/aliases (that’s aliases in your home directory). Add the following:
alias ll=’ls -alG’ alias ls=’ls -aG’
Save your file. Notice that we also included an alias for
ls, which is a valid command. It lives in /bin. Your aliases are executed before the system starts trying to locate your command. So even though
ls is a valid command, every time we execute
ls from this point forward, the system will use our alias and include the -aG parameters.
Now from your terminal, enter the following and try it out:
$ . ~/aliases
|Awesome. Now let’s revisit our *history||grep MailSteward* command. In your aliases file, add the following (I chose hg for history grep):|
Save the file, source it, and try out the new alias:
$ . ~/aliases $ hg MailSteward 42 /Applications/MailSteward.app/Contents/MacOS/MailSteward 1 >& /dev/null 132 /Applications/MailSteward.app/Contents/MacOS/MailSteward 1 >& /dev/null 365 /Applications/MailSteward.app/Contents/MacOS/MailSteward 1 >& /dev/null 469 /Applications/MailSteward.app/Contents/MacOS/MailSteward 1 >& /dev/null $ !42 /Applications/MailSteward.app/Contents/MacOS/MailSteward 1 >& /dev/null $
That’s much better. Now we can find and execute those difficult commands much more easily.
- Related Posts
- History and CTRL-R