93
votes

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.

0

63 Answers 63

3
votes

Display Git branch and status in the prompt

export GIT_PS1_SHOWDIRTYSTATE=true

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")\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w$(__git_ps1 "#%s")\$ '
fi
1
3
votes

Sometimes bash settings are such that rm is aliased to rm -i and thus requires confirmation for each file being deleted. When I work occasionally on such an account, I use \rm to retrieve the original behaviour of rm without changing user configuration.

3
votes

Displays a nice ascii art of the current proccess tree, with the most cpu intensive proccess higlighted.

while true; do 
  clear; 
  pstree $( ps -eo pid --sort %cpu | tail -n 1 ); 
  sleep 1;
done

Kill it with Ctrl + C

3
  • 1
    I prefer using htop ;) Commented Dec 16, 2010 at 14:19
  • Intead of loop you may use watch: watch -n 1 --no-title 'pstree $(ps -eo pid --sort %cpu | tail -n 1)' Commented May 25, 2011 at 4:18
  • this gives you some insight which is not that obvious in htop or top. Cool
    – Ali
    Commented Nov 25, 2011 at 1:12
3
votes

Once so often when you've typed a long command and before finishing it you've realized it won't work right away, because you need to run something else before (e.g. entered git commit -m "long commit message here"), you can hit ^A^K to go to the start of the line and kill it (saving into a buffer), next run a command to fix things, and finally ^Y to paste the killed command, and continue. Saves a lot of re-typing. All this, of course is when readline is in Emacs mode.

Another time-saver: mkdir -p some/nested/dirs/to/be/created creates all the dirs in a path if they're missing.

3
votes

My favourite command is 'find', I use it everywhere... examples:

find . -name "*.log" -exec ls -l {} \; | grep "$(find . -name "*.log" -exec ls -l {} \;| nawk '{print $5}' | sort -n | tail )"

Just display heaviest files in ls -l (long) format.

Then, if you need your code with 0640 permissions, just search:

find . \( \( ! -perm 0640 \) -a \( -name "*.cpp" -o -name "*.h" \) \) -ls | nawk '{print $3"\t"$11}'

or replace:

find . \( -name "*.cpp" -o -name "*.h" \) | xargs chmod 640

Then, do you need a symbol and don't know where is it??

(
  for myObj in $(find . -name "*.o"); do
    gotSym=$(dump -Xany -t $myObj | grep .MY_SYMBOL)
    if ! test "x$gotSym" = "x"
    then
      echo "OBJECT [$myObj] ========================"
      echo "$gotSym"
      echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"^
    fi
  done
)

Newer files than XFILE??

find . -newer XFILE -type f

Yeah, "find" rulez!

2
votes

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

1
  • But why? It's not the eighties anymore - give your eyes some rest and put some colors in there B=). I like having different colors to distinguish different irrsi users.
    – user13742
    Commented Jan 13, 2012 at 0:59
2
votes

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

E.g.:

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

Then, I can do e.g.:

sftp sub
ssh sub

etc.

1
  • It's nice when working with bluetooth; I have E65='XX:XX:XX:XX:XX', s then I can use obex commands without having to type my phone's bluetooth address. Commented Dec 16, 2010 at 14:16
2
votes
# change chmod to file dowloaded --> $_

wget -c http://link/to/file -O /path/to/save/namefile && chmod 0755 $_

# extract tar.bz2 or tar.gz whit less work
# this avoids having to unpack and then move the files to another location, in this case have # already extracted in the desired location

tar jxvf file.tar.bz2 -C /pat/to/extract

# calculator with bc - in bashrc
calc(){ echo "scale=2;$@" | bc;}

# set magic-space in bashrc
bind Space:magic-space                 # !pin<space>  expand last cmd pin...

# alias to open last edited file in vim
alias lvim="vim -c \"normal '0\""

# alias to show your path set
alias path='echo -e ${PATH//:/\\n}'
2
votes

See command output updated every n seconds

watch -n 60 df -h (displays df -h every 60 seconds)

Show statistics about network device wlan0

ip -s link ls wlan0

Show routing table for device eth1

ip route ls dev eth1

Display statistics for all routers packet travels through to reach HOST

mtr --interval 5 HOSTNAME

Consult reverse DNS records for host names on NETWORK

nmap -sL NETWORK

Benchmark a website

ab

Get all links from a web page

lynx -dump http://www.yahoo.com | awk '/http/{print $2}'

Show default gateway

netstat -rn | awk '/UG/{print $2}'

Write standard error to a file

foo 2> errors.txt

Redirect stderr to stdout

foo 2>&1

Redirect both stderr and stdout to the same file.

foo > file.txt 2>&1
2
votes

Replace parts of the previous command:

^search^replace

$ echo a b c d
a b c d
$ ^b c^X
echo a X d
a X d

Great for typos:

$ mkae
-bash: mkae: command not found
$ ^ka^ak
make
[...]
2
  • zsh spelling correction is great for typos. ;-)
    – Mikel
    Commented Apr 7, 2011 at 8:51
  • When you accidentally mix two letters in command name (like in your example with make) shortcut Ctrl+t may be usefull to exchange these letters. Commented May 25, 2011 at 4:41
2
votes

Summarize directory size, with descending human size

du -hs */ | sort -hr

e.g.

10.2G   foo/
4M      bar/
1
  • Nice. As a function: function dush { du -sh "$@" | sort -hr; }
    – ColinM
    Commented Mar 2, 2012 at 22:38
2
votes

double star expansion with zsh (which recursively descends the directory tree, not just one level, something similar to $(find ! -type d):

grep string **/*.cc
1
  • I could not live without that. Commented Jul 31, 2011 at 0:40
1
vote

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 \$ "
1
vote

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.

Example

scp [email protected]:/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
2
  • Funny, my /bin/bash shell does filename expansion with tab just fine. Commented Aug 13, 2010 at 12:53
  • Bash does filename expansion on remote files over ssh? Commented Dec 16, 2010 at 14:13
1
vote

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
1
vote

None of the following 'tricks' is technically challenging or impressive, but they have some impact on the other person. If we can't use our jobs to make our lives happier, then we should think again about some things.

I like alias. My favorite trick is to edit the ~/.bash_aliases on the computer of my gf as she is missing and add a line like:

alias gfname='echo Myname is thinking of you'

or another romantic quotation.

Another "trick" I especially like is:

#!/bin/bash
xaa=123`
for ((a=1; a <= xaa; a++))
do
#sleep 1;
mail -s "Happy Birthday $a" [email protected] < mails.txt
done
exit 0`

where 123 is the of the person to whom I would like to wish happy birthday and mails.txt contains the message that I would like to write as the body of the email. Sleep 1; is sometimes necessary as there is a limit on fork(). You could also use command line arguments $1 etc...

1
vote

I can't live without

set editing-mode vi
set blink-matching-paren on

in my ~/.inputrc.

Activates them in every readline enabled application. Only activating vi command line editing in the shell works via:

set -o vi

Thus, hitting ESC or CTRL+[ gets you the well known vi-command mode. And you can use powerful vi commands everywhere!

1
vote

Use pgrep foo instead of ps aux | grep foo if you want to find how many instances of foo are running and their pids:

e.g. instead of ps aux | grep firefox, use pgrep firefox

1
  • if you prefer full ps aux output: function psg { ps aux | grep "[${1:0:1}]${1:1}" }
    – ColinM
    Commented Mar 2, 2012 at 22:48
1
vote
function calc() { echo $* p | dc }

dc is a RPN calculator; this function enables me to type the expression as the command arguments:

$ calc 5 3 +
8
1
vote

There is a great site for this at: http://www.commandlinefu.com/commands/browse

1
vote

I found the following useful when constantly switching between Windows and Unix/Linux:

alias dir="ls -l"
alias copy="cp"
alias del="rm"
1
vote

Not really a one-liner but I think it's useful. Convert many files to uppercase, for example file_to_upper *php *c. There are many similar cases like converting to lower, renaming all files by suffix/prefix, etc.

file_to_upper ()
{
    for file in "$@"
    do
        if [ ! -f "$file" ]; then
            echo "File $file does not exist";
        else
            mv -f "$file" "`echo "$file" | tr '[a-z]' '[A-Z]'`"
        fi
    done

    return 0
}
1
vote

Mine favorite is to use the python command to make the temporary http server:

python -m SimpleHTTPServer

and accessing files from this machine over the lan as:

http://192.168.1.70:8000

Another one is to download the tar file in extracted form as:

wget -qO - http://192.168.1.70:8000/test.bz2 | tar xjvf -

Here the link can be any over the www and bz2 can be either gz, tgz or bz2 itself for that matter.

1
vote

Backup your fancy dot files automagically

Modular .bashrc --> .bashrc.d

mkdir -p ~/.bashrc.d
cat<<'EOF' >> ~/.bashrc
echo ""
echo -n ".bashrc.d warming up: "
for script in ~/.bashrc.d/* ; do
  if [ -x "$script" ] ; then
    echo -n "${script##*/} "
    . "$script"
  fi
done
echo ""
echo ""
echo "  All systems are go."
echo ""
EOF

Safer rm, compatible with Linux and Mac OS X

rm() {
  local src
  local final_status=0

  for src in "$@"; do
    # Process only non command-line arguments.
    if [[ "$src" != -* ]]; then
      local trash="$HOME/.Trash"
      if [ ! -e "$src" ]; then
        echo "Safer rm: $src: No such file or directory."
        final_status=1
      fi
      # Create the trash directory if needed.
      if [ ! -d "$trash" ]; then
        # Assume Mac trash, but it'll work on *nix too.
        mkdir -p "$trash"
        if [ ! -d "$trash" ]; then
          echo "Safer rm: Unable to create trash directory $trash"
          echo ""
          echo "   Nothing moved or deleted.  Consider carefully:"
          echo ""
          echo "      /bin/rm -rf $src"
          return 1
        fi
      fi
      local dest="$trash/${src##*/}"

      # Find a filename combination which does not already exist.
      if [ -e "$dest" ]; then
        # Try appending ISO datetime.
        dest="$dest.$(date +%Y-%m-%dT%H-%M-%S)"
        if [ -e "$dest" ]; then
          local n=1
          # Try increasing monotony.
          while [ -e "$dest.$n" ]; do
            n = $[n + 1]
          done
          dest="$dest.$n"
        fi
      fi
      echo -n "Safer rm: Trashing $src to $dest ..."
      /bin/mv "$src" "$dest"
      echo " done."
      echo ""
      echo "  To restore:  /bin/mv     '$dest' '$src'"
      echo ""
      echo "  To purge:  /bin/rm -rf '$dest'"
      echo ""
      echo ""
    fi
  done
  return $final_status
}

Super hot 'cd' up action

# Don't ask why I need 15 levels of cd ..

alias ..='cd ..'
alias .2='cd ../..'
alias ...='.2'
alias .3='cd ../../..'
alias .4='cd ../../../..'
alias .5='cd ../../../../..'
alias .6='cd ../../../../../..'
alias .7='cd ../../../../../../..'
alias .8='cd ../../../../../../../..'
alias .9='cd ../../../../../../../../..'
alias .10='cd ../../../../../../../../../..'
alias .11='cd ../../../../../../../../../../..'
alias .12='cd ../../../../../../../../../../../..'
alias .13='cd ../../../../../../../../../../../../..'
alias .14='cd ../../../../../../../../../../../../../..'
alias .15='cd ../../../../../../../../../../../../../../..'

Readline is your one true god.

bind -p | egrep -v '(not|self)' # No existential jokes included.

Terminal fonts

After looking at bazillions of fonts, I use 14 pt Monaco, Anti-aliased with iTerm2.

On Mac (Apps): Try this app that gives key bindings.

KeyCue (tm)(r)(c)($) gives context of almost ANY running app by simply holding command.

1
vote

get the file name with the most recent timestamp in the current directory:

latest () { ls -lrt | tail -1 | awk '{print $NF}' }

2
  • You don't need awk if you change ls -l to ls -1. And remove the -r option and change tail to head: it will be slightly faster and more logical.
    – Mikel
    Commented May 13, 2011 at 11:08
  • In fact, I gave a version of this function in What customizations have you done that does this, but also supports a -<number> option to say how many most recent files to display.
    – Mikel
    Commented May 13, 2011 at 11:15
1
vote

zsh's auto pushd feature:

setopt autopushd

and together with that:

alias dirs='dirs -v'

So that at any time, I can type dirs and I get the history of where I have been:

0   /var/log
1   /tmp
2   /usr/local/bin
3   ~

and then I can cd back into e.g. /usr/local/bin by typing:

cd ~2
1
vote

ReTTY, which allows you to move a running program from one terminal to another. That way, if you have an ncurses program running outside of screen, tmux, or ssh, you can attach it to an ssh session or a networked screen or tmux session by running ReTTY inside the terminal where you want to use the program in question. In other words, it is similar to screen and tmux but with the exceptions that (a) it can only run one program at a time, and (b) it can be run after you start the child process.

0
votes

sync;sync;sync;reboot

can be really useful sometimes. Be careful !

1
  • 3
    On which unix variant is this different from reboot? And why wouldn't you want to shut your system down properly, or at the very least unmount disks as cleanly as possible? Commented Sep 16, 2010 at 19:36
0
votes

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.

3
  • Easier: use zsh or bash 4 and grep -in 'pattern' **/filename Commented Sep 16, 2010 at 19:36
  • 1
    ... or ... find -iname *filename* -exec grep -in '*pattern to search for*' {} \;
    – Eric Smith
    Commented Sep 19, 2010 at 15:51
  • 1
    Or with recent enough versions of GNU grep: grep -r --include='filename' 'pattern' . Commented Oct 6, 2010 at 19:26
0
votes

I find understanding bash key strokes leads to more efficient shelling, and that a lot of them are straight from emacs clarifies their usage (i.e. that meta-XXX is the big brother version of ctrl-XXX command usually).

The "meta" key is usually the "alt" key, but can also be "esc" key. e.g. meta-f can be got with either alt-f or esc f.

For the alt- key mappings to work, you may have to unset "menu access keys" or its equivalent in the console options. Basically if you press alt-f and get the file menu prompt, turn off the alt-key access menus.

ctrl-a / ctrl-e : move to start / end of line basics you can't do without

ctrl-f, meta-f : forward char/word pressing alt-f jumps you forward "1 word" which on command line is pretty much a command or argument

ctrl-b, meta-b : backwards char/word same as alt-f, but backwards to jump backwards through the command line

ctrl-d, meta-d : delete char/word pressing alt-d will delete (to end of) current word under cursor. much faster then holding delete down for 30 secs. Useful when you're tab completing in the middle of something and want to forward delete to the end of word.

ctrl-k : kill line deletes to the end of line

ctrl-u : undo e.g. typing a password, and you know you've got it wrong somewhere, instead of hitting backspace 20 times, just hit ctrl-u. also clears the current command line.

meta-# : insert comment this is great for keeping your command line you're building up as a comment before running it if you need to do something else first. it will go into your command history but not run.

ctrl-r : reverse search searching backwards through your shell history (repeated ctrl-r for next match)

ctrl-g : abort if you're in middle of ctrl-r and want to just get back to where you were typing, just abort your search with ctrl-g

meta-space / ctrl-x ctrl-x : set mark and jump to mark if you need to quickly jump to a position in your command line, first set the mark, then jump back to it with ctrl-x ctrl-x. Note you may have to use esc-space to get the mark set as alt-space is often bound to bringing down the console menu.

ctrl-] <char> : quick jump to <char> jumps forward to the character typed after the ctrl-] on command line. The big brother Meta-ctrl-] <char> jumps backwards.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .