3 minute read

Update (2/20/09): Check out Useful unix tricks – part 2, Useful unix tricks – part 3 and Useful unix tricks – part 4

My current project uses macs for development and linux boxes for build and deployment. I also run linux on my personal computers, so I have learned the value of command line proficiency. Here are a few tricks that I think are worth sharing. I learned some of these on my own, and I picked up others while on this project.

Ctrl+r searches through history

Are you tired of using the up arrow to try to find old commands? Ctrl+r lets you search the history. Type Ctrl+r and start typing part of the old command. Pressing Ctrl+r again finds the next match. Once you find the one you like, just press enter to run it or the left or right arrows to modify it.

Use the history command plus !# to run old commands

Searching the history with Ctrl+r shows you old commands one at a time. Use the history command to see a list of them instead.

% history
    1  cd /tmp
    2  scp user@host:~/my_file .

Now, if you want to run one of those old commands, use !#. For example, to run the scp command again, type:


Source command runs file in current shell

The source command is especially useful when shell config files have changed. For example:

% echo alias ls="ls -F" >> .zshrc
% source .zshrc

This will run the .zshrc file in the current shell. There is no need to open a new terminal to see the changes.

Launch a shell with sudo to run multiple commands

Update (2/16/08): Use “sudo -s” instead of “sudo bash” to start a shell as root.

If you have to run multiple commands with sudo, consider just running “sudo zsh” or “sudo bash” to start a shell as root. If you have sudo rights, but cannot sudo a shell, try this: Run “sudo vi” and then type :shell to open a shell within vi.

Shell expansion using {}

% echo a{a,b,c}
aa ab ac

The {} contain a comma separated list of expansions. One common use is to back up a file. For example, the command:

cp foo.sh foo.sh.old

can be rewritten as:

cp foo.sh{,.old}

zsh is a great shell

zsh is my favorite shell, and I don’t think most people understand how great it is. Here are a few things that it can do:

Tab completion is application specific. For example, type svn and then press tab:

% svn
add       cleanup   diff      info      merge     propedit  resolved  unlock
blame     commit    export    list      mkdir     propget   revert    update
cat       copy      help      lock      move      proplist  status
checkout  delete    import    log       propdel   propset   switch

zsh also tab completes options. For example, type mkdir – and then press tab:

% mkdir -
--context  -Z  -- set SELinux context
--help         -- display help information
--mode     -m  -- set permission mode
--parents  -p  -- make parent directories as needed
--verbose  -v  -- print message for each created directory
--version      -- display version information

These both work for many common programs. Just remember to put the following in your ~/.zshrc file:

autoload -U compinit

I also like changing my prompt to something that looks like


using the following lines in my .zshrc file:

export PS1="%m:%~%# "

zsh adds a -D option to history to display how long each command took. This is helpful since I don’t have to remember to time my commands up front:

% history -D
    1  0:00  cd myproject
    2  0:07  rake test

The filename completion is also a little better than bash. Repeatedly pressing TAB will cycle through all completions.

Tab competion even works across scp/rsync/etc. For example, typing the first line and pressing tab will show all of the files that I can scp:

% scp paul@host:/etc/apache2/
README                 envvars                mods-enabled/          ssl/
apache2.conf           httpd.conf             ports.conf             svn-auth-file
apache2.conf.dpkg-old  magic                  sites-available/       webdav-auth-file
conf.d/                mods-available/        sites-enabled/

However, set up ssh keys before trying this trick unless you want zsh prompting for a password on each completion attempt.