Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Share your command line features and tricks for Unix/Linux. Try to keep it shell/distro agnostic if possible. Interested in seeing aliases, one-liners, keyboard shortcuts, small shell scripts, etc.


locked by Michael Mrozek Nov 6 '11 at 0:41

This question exists because it has historical significance, but it is not considered a good, on-topic question for this site, so please do not use it as evidence that you can ask similar questions here. This question and its answers are frozen and cannot be changed. More info: help center.

63 Answers 63

alias s='sudo'
alias r='rake' # i'm a ruby developer
alias ..='cd ..' # although with autocd feature for zsh this comes packed.

One of my favorites when I forget s:

$ s !! # last command with super user priviledges
If you use ZSH you can do something like bindkey -s '\e[12~' "sudo !!\n" to bind (in this case) F2 to run that command. I have that binding, so when I run something and see the "you forgot 'sudo', fool" error message, I can just stab at F2 in annoyance – Michael Mrozek Aug 10 '10 at 19:50

Not sure if this counts as a "trick", but people seem very unaware of the standard readline hotkeys. Of particular use in shells:

  • Ctrl+U - Cut the current line
  • Ctrl+Y - Paste a line cut with Ctrl+U
  • Ctrl+L - Clear the screen and redraw the current line
  • Ctrl+G - Get a new line and abandon the current one
thanks a lot for Ctrl+L, I have always used 'clear' – phunehehe Aug 11 '10 at 7:08
Just to add a few to these: Ctrl+A to go to the beginning of the line, Ctrl+E to go to the end of the line, Ctrl-K to erase from the cursor to the end of the line. – rsuarez Jan 24 '11 at 15:13

Display a prompt where the hostname is bold. I tried color prompts for a while, but the color would sometimes look bad depending on the background. Bold works for me for light background, dark background, blue backgrounds, etc.

This is in my .bashrc :

    bold=$(tput bold)
    reset=$(tput sgr0)
    export PS1="\u@\[$bold\]\h\[$reset\]:\w \$ "

You can use CDPATH to set up the directory equivalent of PATH; if you try to cd foo and there is no foo in the current directory, the shell will check each of the directories in CDPATH looking for foo in them, and switch to the first one it finds:

export CDPATH="/usr"
cd bin # switches to 'bin' if there is one in the current directory, or /usr/bin otherwise
This might cause issues. See softpanorama.org/Scripting/Shellorama/cdpath.shtml "If $CDPATH is set, the cd built-in will not implicitly append the current directory to it. This means that cd will fail if no valid directory name can be constructed from any of the entries in $CDPATH, even if a directory with the same name as the name given as an argument to cd exists in the current directory." I have been bitten by this, some Makefile's stopped working. Appending . explicitly might help though, but there are some issues with that as well. – ustun Aug 19 '10 at 9:22
vi `which scriptname`

For when you don't know where something lives, and you don't care either.

I don't mean to keep plugging ZSH features, but I keep thinking of them as other people answer :). In ZSH you can do =foo to invoke which automatically, so vi =scriptname – Michael Mrozek Aug 10 '10 at 19:58

CTRL+R in BASH for searching/activating previously executed commands (the contents of ~/.bash_history).

This is often extremely helpful. Running this alias will serve the PWD up over HTTP (indexed) on port 8000:

alias webserver="python -m SimpleHTTPServer"

And because I run make all the time, and spaz out and type too quickly, these aliases are probably my most used (seriously):

alias maek=make
alias mkae=make
alias meak=make
alias amka=make
alias akme=make

And probably my most frequently used piece of BASH is a simple script I call upload. I use it to blit any kind of content to my Linode, and it copies the resulting HTTP URL to my clipboard (middle click). Very useful for pasting stuff to people in IRC:

scp -r $* $user@$host:public_html && {
    URL="http://$host/~$user/$(basename $1)"
    echo "$URL"
    xselection -replace PRIMARY "$URL"

Just a couple. I can post much more later, must get back to work!

alias mk=make Faster to type and less likely to get wrong. Or compile from your editor using a hotkey... – Lars Haugseth Aug 13 '10 at 5:29

This expands somewhat on the !! trick mentioned in this answer. There are actually a bunch of history-related commands that tend to get forgotten about (people tend to stab Up 100 times instead looking for a command they know they typed).

  • The history command will show a list of recently run commands with an event designator to the left
  • !N will substitute the command associated with event designator N
  • !-N will substitute the N th most recent command; e.g. !-1 will substitute the most recent command, !-2 the second most recent, etc.
  • As mentioned in the other answer, !! is shorthand for !-1, to quickly substitute the last command
  • !string will substitute the most recent command that begins with string
  • !?string? will substitute the most recent command that contains string

Word designators can be added on to a ! history command to modify the results. A colon separates the event and word designators, e.g. !!:0. The event designator !! can be abbreviated to just ! when using a word designator, so !!:0 is equivalent to !:0.

  • !:0 will get the command that was executed
  • !:1 will get the first argument (and !:2 the second, etc.)
  • !:2-3 will get the second and third arguments
  • !:^ is another way to get the first argument. !:$ will get the last
  • !:* will get all arguments (but not the command)

Modifiers can also be appended to a ! history command, each prefixed by a colon. Any number can be stacked on (e.g. !:t:r:p).

  • h -- Line up to the base filename
  • t -- Only the base filename
  • r -- Line up to the filename extension
  • e -- Only the filename extension
  • s/search/replacement -- Replace the first occurrence of search with replacement
  • gs/search/replacement -- Replace all occurrences of search with replacement
You, sir, are a command-line God. Even I (as if that matters ;-)) didn't know about the !:h stuff :-) – wzzrd Aug 12 '10 at 14:14
And if you're using Bash (could be the same for certain other shells), M-^ (Meta-^) expands the above history expansion operators for you, just in case you'd like to see what you're actually referring to. – Eric Smith Sep 16 '10 at 14:41
I've never found a use for the ! command things. It just seems bad to me to run a command that I'm not seeing. It'd be so easy to type !-3 instead of !-4, and who knows what could happen. Finding the line number of the command I want to run is usually more a pain than it's worth. Cool tricks though, but I've never found a real use for them. – Falmarri Dec 16 '10 at 18:37
@Falmarri I never use the !-# ones either. I do use !string to run the last command that starts with string, but I generally tab-complete it first (zsh) to make sure I'm running the right thing – Michael Mrozek Dec 16 '10 at 18:42
No! :) "Running !N will run the command ..." is a description too narrow; actually, !N will be substituted by the command ... ; and so on for all the descriptions in the answer. More correct and opening much more useful possibilities! E.g., the mentioned sudo !!. – imz -- Ivan Zakharyaschev Mar 16 '11 at 1:34

This is for zsh, not bash, fyi (if you haven't used it, you won't regret trying it out). This is really useful for quickly typing out long paths for scp transfers. It works just like using to complete or list available filenames/directories.


scp webdev@example.com:/home/webdev/domains/example.com/http.public/long<tab>

will complete the path to /home/webdev/domains/example.com/http.public/longdirname.

I'm bad at examples, but that should give you the idea. Try it out, it can really save you fingers from typing.

# SSH Completion
zstyle ':completion:*:scp:*' tag-order \
   files users 'hosts:-host hosts:-domain:domain hosts:-ipaddr"IP\ Address *'
zstyle ':completion:*:scp:*' group-order \
   files all-files users hosts-domain hosts-host hosts-ipaddr
zstyle ':completion:*:ssh:*' tag-order \
   users 'hosts:-host hosts:-domain:domain hosts:-ipaddr"IP\ Address *'
zstyle ':completion:*:ssh:*' group-order \
   hosts-domain hosts-host users hosts-ipaddr
zstyle '*' single-ignored show

bash -- insert preceding line's final parameter

alt-. the most useful key combination ever, try it and see, for some reason no one knows about this one.

press it again and again to select older last parameters.

great when you want to do something more to the argument/file you used just a moment ago.

You can also use !$ to refer to the last arg in the previous command. This is useful because it works in scripts as well as interactively. (Works in bash & zsh) – Jerry H. Aug 10 '10 at 20:07
Each time you hit alt-. it will go to the previous command and pull the last argument from it. So if you want the last argument from three commands ago, just hit alt-. three times. – clee Aug 20 '10 at 20:09
This is the default key binding for the yank-last-arg readline command, so it should work with any program linked against readline, not just BASH or ZSH. – James Sneeringer Oct 5 '11 at 16:58

If a command takes stdin input, you can read the input from a file with <filename. This can appear anywhere in the command, so these lines are equivalent:

cat filename
cat <filename
<filename cat

This is particularly useful for grep, as it allows you to place the expression at the end of the line, so you can quickly modify a grep command it by hitting Up, without needing to scroll left to get past the filename:

<filename grep 'expression'
A good tip! Worth noting that this doesn't actually reorder the arguments to the command. Instead it pipes the file into the process' STDIN, as grep now has no file argument it defaults to reading from STDIN. Understanding this will open many opportunities to use this technique with other commands and also help people to understand what's going on when things don't work as expected. For more info look up pipes and redirectors: dsj.net/compedge/shellbasics1.html – chillitom Aug 10 '10 at 20:23

Since I'm usually halfway into a command line before wanting to search (CTRL-R in bash) I have the following in my .bashrc

bind '"\e[A"':history-search-backward
bind '"\e[B"':history-search-forward

This means that if I type cd then press up/down I can see all the options that I have cd'd to. Basically I use this for often used dirs. Like "cd w" and I'm ending up going through all the workspaces I use lots.


Two bash functions which save me many key strokes.

Do automatically an ls after every successfull cd:

function cd {
    builtin cd "$@" && ls

Go up n levels:

# Usage .. [n]
function .. (){
    local arg=${1:-1};
    local dir=""
    while [ $arg -gt 0 ]; do
        arg=$(($arg - 1));
    cd $dir #>&/dev/null
I never realized you could do builtin foo to get around having a function defined cd; I've been using chdir in my functions. Handy – Michael Mrozek Aug 11 '10 at 13:39
I do the same as you for cd, but I have a few more sanity checks in and avoid doing ls in non-interactive mode: cd() { builtin cd -- "$@" && { [ "$PS1" = "" ] || ls -hrt --color; }; } – jmtd May 10 '11 at 14:27

One thing that saves me a lot of time is the pushd/popd commands. These guys let you create a stack of directories and reduce typing a lot:

/foobar/ > pushd /src/whatever/foo/test
/foobar/src/whatever/foo/test > make run
/foobar/src/whatever/foo/test > popd
/foobar/ > make
Yes! alias u=pushd; alias o=popd – cannedprimates Aug 15 '10 at 9:57
.. and what do u and o stand for here? – deizel Aug 19 '10 at 11:32
Looks like the second letter of the command, since they both start with p, you can't use that for both. – camh Sep 16 '10 at 10:20

I love chucking as much stuff as I can into my PS1. Some useful things to remember:

\e[s and \e[u save and unsave the cursor position respectively. I use this to create an 'info-bar' at the top of the screen, a couple of lines long, which can fit more stuff. Example:

PS1='\[\e[s\e[7m\e[1;1H\]\w\n\t        \j / \! / \#\[\e[u\e[0m\e[33;1m\][\u@\h \[\e[34m\]\W]\[\e[0m\]\$ '

Combine with alias clear='echo -e "\e[2J\n"'. Try it out!

Also, the PROMPT_COMMAND variable defines a command to execute before the PS1 every time.

Another one is the bg command. If you forget to put & at the end of a command, just press ^Z and type bg, and it runs in the background.


Display Git branch and status in the prompt


if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]$(__git_ps1 "#%s")\$ '
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w$(__git_ps1 "#%s")\$ '
Also check vcprompt: vc.gerg.ca/hg/vcprompt The same idea, and supports git, mercurial and subversion. – Sergio Acosta Aug 26 '10 at 9:13

This is usually in my startup script (.bashrc, .profile, whatever)

shopt goodness, check the comments:

shopt -s cdspell        # try to correct typos in path
shopt -s dotglob        # include dotfiles in path expansion
shopt -s hostcomplete   # try to autocomplete hostnames

An alias that save keystrokes: mkdir and cd into it:

mkcd () { mkdir -p "$@" && cd "$@"; }

And last but not least, I've given up on memorizing tar syntax, so:

extract () {
    if [ -f $1 ] ; then
        case $1 in
            *.tar.bz2)  tar xjf $1      ;;
            *.tar.gz)   tar xzf $1      ;;
            *.bz2)      bunzip2 $1      ;;
            *.rar)      rar x $1        ;;
            *.gz)       gunzip $1       ;;
            *.tar)      tar xf $1       ;;
            *.tbz2)     tar xjf $1      ;;
            *.tgz)      tar xzf $1      ;;
            *.zip)      unzip $1        ;;
            *.Z)        uncompress $1   ;;
            *)          echo "'$1' cannot be extracted via extract()" ;;
        echo "'$1' is not a valid file"
+1, why didn't I think of that? (extract) – MAK Sep 19 '10 at 16:48

my favorite feature is NO COLORS! =)

TERM=xterm-mono or TERM=linux-m depends on OS...

I really like black and white IRSSI, mc and any other "Text user interface" tool


Execute last command as root:

sudo !!

Another useful ZSH trick:

Treat the output of a command as a file:

emacs =(hg cat -r 100 somefile)

This opens an old version of a Mercurial-tracked file in emacs for syntax-highlighted viewing. Without that, I would have to mess around with hg revert, hg archive, or explicitly send hg cat output to a temporary file.

Of course, this works with any program that opens files, and any program that prints to standard output.

You can do this in bash with the <() – ScaryAardvark Aug 11 '10 at 9:45

ZSH has global aliases. It expands the alias anywhere in the command line. I've found this useful for hostnames:


alias -g sub='sub.domain.tld'

Then, I can do e.g.:

sftp sub
ssh sub



diff the output of two commands without creating a temporary file manually (bash):

diff <(ls dir1) <(ls dir2)

A ZSH-specific feature is suffix aliases, set by giving alias the -s flag:

alias -s ext=program

If a given extension has a suffix alias, you can execute a file with that extention directly, and ZSH will launch the given program and pass the filename as an argument. So if the above alias is in effect, these lines are equivalent:

program /path/to/foo.ext

One of my all-time favorite ZSH features is named directories. You can export a variable with a given name, with a value that points to a certain path:

export foo=/usr/bin

Now you can use ~foo in a command to refer to /usr/bin:

cd ~foo
cat ~foo/filename

My favorite is

man 7 ascii

Simple and so very useful.

alt text

Have a look at this website commandlinefu.com.

You can also have a look at these four articles by Peteris Krumins on his blog

The separate ascii program is also useful. Besides printing a table, it lets you query for one or more individual characters. – Matthew Flaschen Aug 15 '10 at 5:24

If you are a fast typist, these come in handy:

alias grpe='grep --color=tty'
alias gpre='grep --color=tty'
alias rgep='grep --color=tty'
alias gerp='grep --color=tty'

This macro helps you compute totals of a column of output: file sizes, bytes, packets, all you have to do is specify the column that you want to add:

total ()
        if [ x$1 = x ]; then set `echo 1`; fi
        awk "{total += \$$1} END {print total}"

You use it like this for example, with no arguments, it adds the total of the first column:

du | total

If you provide the argument, it will sum that column, for example, this gives you the total number of bytes used by all the C# files in /tmp:

ls -l /tmp/*cs | total 5

Sometimes your console gets messed up because you accidentally viewed a binary file (cat /bin/ls for example), you can restore the terminal with this shell function:

restaura ()
    perl -e 'print "\e)B";'

I like my ls to use characters to distinguish the class of files, and also to hide the backup files generated by my editor (backup files end with the ~ character):

alias ls='ls -FB'
Far as I'm concerned, "fast" doesn't count if I'm not accurate. You may also want to look at the GREP_COLORS and GREP_OPTIONS variables. – Andy Lester Oct 8 '10 at 22:58
s/fast/sloppy/ – Josh Dec 14 '10 at 16:00
I use reset where you use restaura. – jmtd May 10 '11 at 13:04

The ampersand. It puts your command in the background, so you can continue typing.

$> sudo updatedb &

Working along, and after a while you see:

[1] 17403

And your process is done! Great for things where you don't need to wait for them to terminate.

And if your app is GUI, you probably don't want it to keep in jobs. Append &! to background the job and disown it from the shell! – progo Mar 15 '11 at 11:01
@progo: It turns out that prepending the command with nohup accomplishes this. – Nathan Osman May 6 '11 at 6:37

The screen command. It basically saves your command line session for when you come back. It's sort of a terminal manager, like a window manager. That way, in a single terminal session, you can have multiple virtual terminals going on. It's very cool.

If one uses screen, this shell function (put it into .bashrc) is extremely useful:

function scr {
    if screen -ls | grep -q Main; then
         # reattach to Main: 
         screen -xr Main
         # name session "Main":
         screen -S Main

upon typing scr, it will check if your main session exists and will attach to it. Otherwise it will create it.

I'd recommend tmux or dvtm over screen. They are more modern and cleaner replacements. – deltaray Nov 20 '11 at 3:59

Tab completion. How bad would it suck if you had to type out all the characters of every path?

There's suicide linux. If you incorrectly type the command - it does rm -fr /. So yeah, Tab completion is pretty vital... – Eimantas Aug 21 '10 at 4:58

I have folders named in my home folder as Document, Downloads, Temp, etc with the first letter in uppercase. When I work on the terminal it's annoying to shift press the first key when you are cd'ing into a directory. Just key in the following in your terminal and bash would auto-correct the case for you.

shopt -s nocaseglob

My personal favorite is

find . -name <i>filename</i> | xargs grep -in '<i>pattern to search for</i>'

What the above command does is find a file of name x and then searches said file for whatever pattern you are looking for. Incredibly useful if you are looking for a particular bit of code in a file that's somewhere in your subdirectories.

... or ... find -iname *filename* -exec grep -in '*pattern to search for*' {} \; – Eric Smith Sep 19 '10 at 15:51
Or with recent enough versions of GNU grep: grep -r --include='filename' 'pattern' . – Gilles Oct 6 '10 at 19:26

Not the answer you're looking for? Browse other questions tagged or ask your own question.