93

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.

mattdm
  • 40,245
cmcginty
  • 2,683
  • 4
  • 21
  • 12

63 Answers63

88

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
Michael Mrozek
  • 93,103
  • 40
  • 240
  • 233
  • 3
    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
  • @Eric Ah, cool. In zsh it's Tab – Michael Mrozek Sep 16 '10 at 17:30
  • This is crazy ... I think I will have a different kind of respect for question mark from now on. Thanks for this answer, awesome. – Patkos Csaba Sep 25 '10 at 21:48
  • I should get these tattooed as I learned and forgot these shortcuts about a hundred times. – al. Oct 22 '10 at 13:07
  • 1
    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
  • 1
    @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
  • 1
    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 01:34
  • 1
    To run previous commands looked up by a string, I usually just press Ctrl-R. Multiple Ctrl-R will dig deeper into the history. This way, I see the found command immediately, and can discard it and look further. Ctrl-G escapes from this mode. The only inconvenience is that Ctrl-R is for bash; in Emacs, to browse through the history of input commands and values (for M-x or other read values) one uses Meta-R instead (Meta-R is also used in eshell in Emacs). So I often mess them up. – imz -- Ivan Zakharyaschev Mar 16 '11 at 01:45
  • 1
    @imz Good point; fixed – Michael Mrozek Mar 16 '11 at 02:23
  • What I wanted to convey with a one of my comments here (that for repeating a previous command, there is another convenient way, namely Ctrl-r) is actually already covered in more detail in another question -- http://unix.stackexchange.com/q/541/4319 -- I have just stumbled upon. – imz -- Ivan Zakharyaschev Mar 16 '11 at 09:33
  • 1
    @Falmarri The real strength of these commands is that they are shell-agnostic - they work in /bin/sh, not just bash. That doesn't really matter nowadays, but it's something. –  Apr 12 '11 at 02:20
64

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.

chillitom
  • 653
  • 11
    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) –  Aug 10 '10 at 20:07
  • 4
    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
  • 2
    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 05 '11 at 16:58
  • In vi mode, I had to rebind yank-last-arg as per this answer: http://superuser.com/questions/18498/last-parameter-of-last-command-in-bash-in-vi-mode/18507#18507 – Jeromy Anglim Oct 08 '11 at 13:14
  • In xterm, meta-. produces ®, but you can use esc instead of meta (in general in bash), so esc-. instead. – derobert Nov 11 '11 at 22:01
  • Note that there is a difference between alt-. and !$. !$ gets the last arg from the previous command you ran. Alt-. pulls the last arg from the previous history line. – deltaray Nov 20 '11 at 03:46
49

My favorite is

man 7 ascii

Simple and so very useful.

   Oct   Dec   Hex   Char                        Oct   Dec   Hex   Char
   ────────────────────────────────────────────────────────────────────────
   000   0     00    NUL '\0' (null character)   100   64    40    @
   001   1     01    SOH (start of heading)      101   65    41    A
   002   2     02    STX (start of text)         102   66    42    B
   003   3     03    ETX (end of text)           103   67    43    C
   004   4     04    EOT (end of transmission)   104   68    44    D
   005   5     05    ENQ (enquiry)               105   69    45    E
   006   6     06    ACK (acknowledge)           106   70    46    F
   007   7     07    BEL '\a' (bell)             107   71    47    G
   010   8     08    BS  '\b' (backspace)        110   72    48    H
   011   9     09    HT  '\t' (horizontal tab)   111   73    49    I
   012   10    0A    LF  '\n' (new line)         112   74    4A    J
   013   11    0B    VT  '\v' (vertical tab)     113   75    4B    K
   014   12    0C    FF  '\f' (form feed)        114   76    4C    L
   015   13    0D    CR  '\r' (carriage ret)     115   77    4D    M
   016   14    0E    SO  (shift out)             116   78    4E    N
   017   15    0F    SI  (shift in)              117   79    4F    O
   020   16    10    DLE (data link escape)      120   80    50    P
   021   17    11    DC1 (device control 1)      121   81    51    Q
   022   18    12    DC2 (device control 2)      122   82    52    R
   023   19    13    DC3 (device control 3)      123   83    53    S
   024   20    14    DC4 (device control 4)      124   84    54    T
   025   21    15    NAK (negative ack.)         125   85    55    U
   026   22    16    SYN (synchronous idle)      126   86    56    V
   027   23    17    ETB (end of trans. blk)     127   87    57    W
   030   24    18    CAN (cancel)                130   88    58    X
   031   25    19    EM  (end of medium)         131   89    59    Y
   032   26    1A    SUB (substitute)            132   90    5A    Z
   033   27    1B    ESC (escape)                133   91    5B    [
   034   28    1C    FS  (file separator)        134   92    5C    \  '\\'
   035   29    1D    GS  (group separator)       135   93    5D    ]
   036   30    1E    RS  (record separator)      136   94    5E    ^
   037   31    1F    US  (unit separator)        137   95    5F    _
   040   32    20    SPACE                       140   96    60    `
   041   33    21    !                           141   97    61    a
   042   34    22    "                           142   98    62    b
   043   35    23    #                           143   99    63    c
   044   36    24    $                           144   100   64    d
   045   37    25    %                           145   101   65    e
   046   38    26    &                           146   102   66    f
   047   39    27    '                           147   103   67    g
   050   40    28    (                           150   104   68    h
   051   41    29    )                           151   105   69    i
   052   42    2A    *                           152   106   6A    j
   053   43    2B    +                           153   107   6B    k
   054   44    2C    ,                           154   108   6C    l
   055   45    2D    -                           155   109   6D    m

   056   46    2E    .                           156   110   6E    n
   057   47    2F    /                           157   111   6F    o
   060   48    30    0                           160   112   70    p
   061   49    31    1                           161   113   71    q
   062   50    32    2                           162   114   72    r
   063   51    33    3                           163   115   73    s
   064   52    34    4                           164   116   74    t
   065   53    35    5                           165   117   75    u
   066   54    36    6                           166   118   76    v
   067   55    37    7                           167   119   77    w
   070   56    38    8                           170   120   78    x
   071   57    39    9                           171   121   79    y
   072   58    3A    :                           172   122   7A    z
   073   59    3B    ;                           173   123   7B    {
   074   60    3C    <                           174   124   7C    |
   075   61    3D    =                           175   125   7D    }
   076   62    3E    >                           176   126   7E    ~
   077   63    3F    ?                           177   127   7F    DEL

Have a look at this website commandlinefu.com.

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

terdon
  • 242,166
Moeb
  • 101
46

Execute last command as root:

sudo !!
Alex B
  • 4,478
42

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
Michael Mrozek
  • 93,103
  • 40
  • 240
  • 233
  • 5
    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
  • Ctrl+L corresponds to the FormFeed ascii character. It will typically redraw the screen in text applications with a screen window (e.g. vim, less, mc, etc). Nice if the screen has been "polluted" by some output from another program. – hlovdal Mar 17 '11 at 22:13
  • Adding to the list of hot-keys: Ctrl+W to cut one word backwards, Alt+F to go forward one word, Alt+B to go one word backward in a line. I like Ctrl+Y and Shift+Insert because you can have two copied lines. One with Ctrl+U ( paste it with Ctrl+Y ) and at the same time you can copy another word ( select the line ) paste with (Shift+Insert). –  Feb 24 '12 at 19:26
35

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!

Aaron Bockover
  • 161
  • 1
  • 5
  • 8
    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 05:29
  • BTW Zsh has built-in spelling correction that is very good at correcting simple typos. – Adam Byrtek Sep 15 '10 at 17:14
  • Also in zsh, I think the default is when you hit the up key it does a history search as if you had hit ctrl r. Might not be the default, but it's a setting. – Falmarri Dec 16 '10 at 18:40
  • I'd consider alias m=make, or even m=make -j6 or similar -- except I already use alias m=mutt – jmtd May 10 '11 at 12:54
31

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

diff <(ls dir1) <(ls dir2)
Alex B
  • 4,478
  • This is also super useful for comm as it takes files only, but in a lot of cases that's a waste of inodes. – Marcin May 05 '11 at 14:11
30

Pretty basic, but people don't seem to know, returns you to the previous dir:

cd -
29

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()" ;;
        esac
    else
        echo "'$1' is not a valid file"
    fi
}
Sebastian
  • 8,817
  • 4
  • 40
  • 49
Sygo
  • 336
  • 5
    +1, why didn't I think of that? (extract) – MAK Sep 19 '10 at 16:48
  • I have a similar function to mkcd only that I name id md. However the using "$@" as argument to cd does not make any sense since you cannot cd to more than one single directory. "$@" will work for mkdir, but then you are handling arguments differently for mkdir and cd, so I would rather suggest md () { mkdir -p "$1"; cd "$1" } – hlovdal Mar 17 '11 at 22:20
  • how do I add those commands? just paste as is to .bashrc or add "alias" before them? – Asaf Nov 18 '11 at 19:34
29

Brace Expansion:

Brace expansion is a mechanism by which arbitrary strings may be generated.

It allows you to replace tedious lines like:

mv loong/and/complex/file/name loong/and/complex/file/name.bacukup

with a shorter instance

mv loong/and/complex/file/name{,backup}

some other uses

# to display the diff between /etc/rc.conf and /etc/rc.conf.pacsave
diff /etc/rc.conf{,.pacsave}

# to list files in both /usr/share and /usr/local/share
ls /usr/{,local}/share 

Arithmetic Expansion:

Arithmetic expansion allows the evaluation of an arithmetic expression and the substitution of the result. The format for arithmetic expansion is:

$((expression))

The expression is treated as if it were within double quotes, but a double quote inside the parentheses is not treated specially. All tokens in the expression undergo parameter expansion, string expansion, command substitution, and quote removal. Arithmetic expansions may be nested.

$ a=1
$ b=2
$ echo $(( a+(b*2) ))
5
Stefan
  • 25,300
21

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
        dir="../$dir"
        arg=$(($arg - 1));
    done
    cd $dir #>&/dev/null
}
Maik
  • 276
  • 4
    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
  • Awesome. Just add -F to ls in the cd function and it's perfect (for me)! – frabjous Aug 22 '10 at 02:49
  • 2
    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
17

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
jacksonh
  • 3,734
  • 1
  • 20
  • 13
17

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.

mendicant
  • 369
  • 3
  • 7
  • This one is really great ! It extends the arrows behaviour without breaking their basic functionality.Thanks ! – philfr Mar 16 '11 at 08:41
14

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
    else
         # name session "Main":
         screen -S Main
    fi
   }

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

Sebastian
  • 8,817
  • 4
  • 40
  • 49
user394
  • 14,404
  • 21
  • 67
  • 93
13

If you need to edit a particularly long command line in bash

^X^E (Ctrl-X Ctrl-E) 

will open it in the editor ($EDITOR).

In zsh you can get the same behaviour by adding this to .zshrc:

autoload edit-command-line
zle -N edit-command-line
bindkey '^X^e' edit-command-line 
redacted
  • 1,076
12

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'
11
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
Adam Byrtek
  • 1,339
Eimantas
  • 1,486
  • 3
  • 23
  • 31
  • 2
    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
  • Poor F2 key... .) – Eimantas Aug 10 '10 at 19:55
  • I use this all the time. I constantly forget to type sudo before editing my hosts file. If that happens I just run sudo !!. +1 – Brian Wigginton Jan 13 '11 at 22:16
10

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'
Michael Mrozek
  • 93,103
  • 40
  • 240
  • 233
  • 3
    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: http://www.dsj.net/compedge/shellbasics1.html – chillitom Aug 10 '10 at 20:23
  • @chill Good points; the tip was actually phrased so poorly as to be essentially wrong. I rewrote it based on your comment – Michael Mrozek Aug 10 '10 at 20:34
  • Something I found out recently: you can redirect input to loops (for, while, etc.). See http://www.faqs.org/docs/abs/HTML/redircb.html. – Lucas Jones Aug 11 '10 at 10:41
  • Conventionally you put the redirection on the end. Whilst the pipeline metaphor looks better with <input foo | bar | baz >output, it doesn't work if you try mixing in some shell looping primitives like while or for in the middle. So I gave up and just put it at the end as per convention. – jmtd May 10 '11 at 13:07
  • @jmtd Well, putting it on the end eliminates "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" – Michael Mrozek May 10 '11 at 13:42
  • Yes I am aware of that. I've walked this very road. My point was, whilst it does give you the advantage of more quickly editing the last argument on a command-sequence, it also breaks if you need to use or introduce a shell loop. So I found the convenience was not outweighed by that problem. – jmtd May 11 '11 at 10:59
9

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
Michael Mrozek
  • 93,103
  • 40
  • 240
  • 233
  • 3
    This might cause issues. See http://www.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 09:22
9
vi `which scriptname`

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

Matt Simmons
  • 1,070
  • 1
  • 8
  • 14
  • 8
    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
  • If you are having trouble looking up the backtick character you can also use $(scriptname) – Patrick Oct 16 '10 at 08:20
9

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.

user394
  • 14,404
  • 21
  • 67
  • 93
8

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

user394
  • 14,404
  • 21
  • 67
  • 93
7

Umount last mounted device:

mount /media/whatever
...
u!mo

!mo expands to the last command that started with mo (at least in bash). Sometimes one does mv in the middle, so u!m won't work as often.

7

I have this in my .bashrc

#shortcut for CTRL+C and CTRL+V
alias c-c='xclip -sel clip'
alias c-v='xclip -o -sel clip'

 

function find-all() {
    python -c "import re
import sys
for i in re.findall('$1', sys.stdin.read()):
    if type(i) == type(''):
        print i
    else:
        print i[0]"
}

And when I have html source code in clipboard and want to find all links I use

c-v | find-all 'href="([^"]*)"' | c-c

And I have all urls in clipboard

I also have this function

function lsq(){
    ls -lh $@ | tr -s ' ' | cut -d' ' -f5,8
}

which display size (human readable) and filename.

alias temp='cat /proc/acpi/thermal_zone/THRM/temperature'

this alias is for show temerature

function separate() {
    python -c "import sys,re; print '$1'.join(re.split('\s*', sys.stdin.read().strip()))";
}

with this function I can calculate product or sum of arguments.

alias sum='separate + | bc'
alias product='separate * | bc'

function split-join() {
    python -c "import sys,re; print '$2'.join(re.split('$1', sys.stdin.read().strip()))";
}

This is usefull function which split standard input separated by regex and then join the result.

function factorial() {
    seq -s* $1 | bc
}

factorial function

function wiki() { dig +short txt $1.wp.dg.cx; }

This function display wiki text over DNS

I also have three color funcions

function blue() {
    echo -e "\x1b[34m\x1b[1m"$@"\x1b[0m";
}

function green() {
    echo -e "\x1b[32m\x1b[1m"$@"\x1b[0m";
}

function red() {
    echo -e "\x1b[31m\x1b[1m"$@"\x1b[0m";
}

 

function md5check() {
    test `md5sum $2 | cut -d' ' -f1` = "$1" && green [OK] || red [FAIL]
}

This function validate file md5 hash.

this will show error message for a given code

function strerror() { python -c "import os; print os.strerror($1)"; }

You can print all messages with

alias all-errors='for i in `seq 131`; do echo -n "$i: "; strerror $i; done'
jcubic
  • 9,932
6

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.

5

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:

/path/to/foo.ext
program /path/to/foo.ext
Michael Mrozek
  • 93,103
  • 40
  • 240
  • 233
  • This is one thing I really missed about Windows... until I realized that "program" was always emacs, so I stopped using shell to open files and just used C-x C-f (duh). – harpo Feb 16 '11 at 04:11
5

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
~foo/ls
cat ~foo/filename
Michael Mrozek
  • 93,103
  • 40
  • 240
  • 233
  • if your prompt displays the current working directory, the names of the variables will also be used there as far as I remember. – Andre Holzner Jun 18 '11 at 16:34
4

See this question.

When you run ps ax | grep string:

[steve@sage-arch ~]$ ps ax | grep 'openbox'
 3363 ?        Ss     0:00 /usr/bin/openbox
 3382 ?        Ss     0:00 /usr/bin/ssh-agent -- /usr/bin/openbox-session
 3386 ?        S      0:00 /bin/sh /usr/bin/openbox-session
 3388 ?        S      0:00 /bin/sh /usr/bin/openbox-session
 3389 ?        S      0:00 /bin/sh /usr/bin/openbox-session
 3390 ?        S      0:00 /bin/sh /usr/bin/openbox-session
 5100 pts/0    S+     0:00 grep openbox

the last line containing grep is somethings a bit anoying

You can rid yourself of this by running ps ax | grep '[s]tring':

[steve@sage-arch ~]$ ps ax | grep '[o]penbox'
 3363 ?        Ss     0:00 /usr/bin/openbox
 3382 ?        Ss     0:00 /usr/bin/ssh-agent -- /usr/bin/openbox-session
 3386 ?        S      0:00 /bin/sh /usr/bin/openbox-session
 3388 ?        S      0:00 /bin/sh /usr/bin/openbox-session
 3389 ?        S      0:00 /bin/sh /usr/bin/openbox-session
 3390 ?        S      0:00 /bin/sh /usr/bin/openbox-session

update: or just run pgrep string

Stefan
  • 25,300
  • yeah, very useful. You should quote openbox though ('[o]penbox'). The brackets will work as kind of a glob, so if there is openbox in your directory (say you're in /usr/bin) bash will just use openbox, which will prevent the grep trick. – Rich Homolka Oct 21 '10 at 19:58
4
  • The do-nothing command : as in

    while :; do :; done
    
  • Brace expansion in combination with for loops:

    for c in {1..3}; do :; done
    
  • ! operator and short circuiting operators || and &&

    [ -d /tmp/dir ] || mkdir /tmp/dir
    
    if ! ping 34.41.34.1; then :; fi
    
  • using sub shells instead of pop/push (comes in handy in scripts)

    ~$ ( cd /tmp; echo $PWD )
    /tmp
    ~$
    
  • the kind-of what-is command type

    ~$ type type
    type is a shell builtin
    ~$ type ls
    ls is aliased to `ls --color=auto'
    ~$ f(){ :; }
    ~$ type f
    f is a function
    f () 
    { 
         :
    
    }
    
  • also very nice: here-strings

    ~$ cat <<<"here $PWD"
    here /home/yourname
    ~$
    
  • and my favorite: redirection on a list of commands

    { w; ps; ls /tmp; } 2>/dev/null |less
    
wnrph
  • 1,444
3

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.

Lucas Jones
  • 1,716
  • thanks for the bg, when I have a program running in the background and accidentally press fg I don't know how to push it back :D – phunehehe Aug 11 '10 at 07:15
  • I like a clean PS1 so I put most of the stuff I want into my screen bottom line... – Josh Dec 14 '10 at 16:01
3

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
Bauna
  • 551
3

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.

mouviciel
  • 1,235
3

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

Stefan
  • 25,300
3

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.

alex
  • 7,223
3

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!

D4RIO
  • 1,576
2

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

Summarize directory size, with descending human size

du -hs */ | sort -hr

e.g.

10.2G   foo/
4M      bar/
2

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

grep string **/*.cc
2

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

holms
  • 276
  • 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. –  Jan 13 '12 at 00:59
2

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.

  • 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. – André Paramés Dec 16 '10 at 14:16
2

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
Gert
  • 9,994
2
# 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}'
SergioAraujo
  • 459
  • 6
  • 8
1

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" address@example.com < 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

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!

maxschlepzig
  • 57,532
1

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.

SHW
  • 14,786
  • 14
  • 66
  • 101
1

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.

dhchdhd
  • 348
1

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

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

Moses Xu
  • 121
1

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

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.

mmirate
  • 101
1

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
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
André Paramés
  • 802
  • 5
  • 12
1

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

1

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 \$ "
Stefan Lasiewski
  • 19,754
  • 24
  • 70
  • 85
1

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

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

alias dir="ls -l"
alias copy="cp"
alias del="rm"
artdanil
  • 176
1

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
tsudot
  • 203
1

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
}
sakisk
  • 2,873
0

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.

Michael Mrozek
  • 93,103
  • 40
  • 240
  • 233
0

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.

markf
  • 111
0

My favs are below. I use most of them regularly

df -k (check filesystems) kill or kill -9 (kill a process) set -o vi (set your command line to vi) topas (performance tool) mount/unmount

oh yeah and how could I forget the > (to redirect output to a file) ls > /tmp/tmp.txt

Many more but some off the top of me head.

0

I often notice, just after starting a 15-minute-command, that I would have wanted to add some other stuff to the command line using && . Instead of interrupting the already-running job, I tend to use at to queue the second one, giving myself a longer time I don't need to watch the terminal.

Generally, at queues jobs for execution at a given time:

$ at 14:30
> myscript
> anotherscript
> <CTRL-D>

Entries to the queue can be viewed with atq and removed with atrm.

Another addition to the bash prompt customization tips: I like to invert the prompt, as this gives good visual cues where command output begins and ends in long terminal listings. This works well for both bright and dark backgrounds.

export PS1="\[\e[7m\][\u@\h \w]\[\e[0m\]$ "
jstarek
  • 1,710
0

sync;sync;sync;reboot

can be really useful sometimes. Be careful !

0
find path expr -exec ls -ld {} \;

Nice easy way to see ownership, permissions, sizes (if files), and other characteristics of whatever your 'find' expression returns.