Tip: ^ and ! in the shell

I’m astounded. So don’t people know about using ^ and ! in the shell?!? Last week I watched an experienced Linux user carefully hit the ↑ cursor key to get a previous line of history, then ←&→ just to make a simple edit!

Here’s my 30 second guide:

!! Repeat the previous command. Example:

$ ls
bin  d  Desktop  rpmbuild  tmp
$ !!
bin  d  Desktop  rpmbuild  tmp
!-2 (etc) Repeat the command 2 previously (so !! = !-1), or for any number previously. This is the most useful I think.
^foo^bar Replace foo with bar in the previous command. eg:

$ ls -l /etx/httpd/conf.d/local.conf
ls: cannot access /etx/httpd/conf.d/local.conf: No
such file or directory
$ ^etx^etc
ls -l /etc/httpd/conf.d/local.conf 
-rw-r--r-- 1 root root 76 2009-07-16 14:59 /etc/httpd/conf.d/local.conf
!foo Run the most recent command that started foo, eg:

$ !ls
ls -l /etc/httpd/conf.d/local.conf 
-rw-r--r-- 1 root root 76 2009-07-16 14:59 /etc/httpd/conf.d/local.conf

Today I discovered that these are called event designators. When I first saw someone using them it was on an Apollo workstation circa 1991, and I pretty quickly picked these up myself.


Filed under Uncategorized

18 responses to “Tip: ^ and ! in the shell

  1. Shane Falco

    Different strokes for different folks. Despite knowing this functionality, its value does not resonate with me and it feels too dangerous. Call me safe and paranoid, but I prefer to see each command before I hit enter.

    Also, regarding your replacement example, it’s almost always faster with potentially fewer keystrokes for me to bring up the previous command and edit it.

  2. red

    Didn’t know about the ^x^y 🙂 Thanks for the hint…I hope I’ll remember that one!

  3. Allen Halsey

    Thanks for the tip about ^. Seems useful.

    Regarding history expansion, I disabled it in bash after getting errors like this:

    $ echo “Hello World!”
    bash: !”: event not found

    In addition, I don’t like executing a command without having a chance to see and edit it on the command line first. I wouldn’t take a chance on !-3.

    Ctrl-P and Ctrl-R suit my needs fine.

  4. Seth Vidal

    A lot of folks don’t use those b/c they commonly use multiple shells and/or multiple unixes and find them unreliable across a wide variety of versions of shells.

    • rich

      I’m pretty sure ! is widely supported. Note I first saw it used on an Apollo workstation running original csh (not even tcsh 🙂 ). Not sure about ^a^b.

      However they didn’t work on Minix’s very simple Bourne-shell-alike.

      Having said that does anyone use anything which isn’t bash these days? Solaris used to default to ksh IIRC, but I thought they all shipped with bash now. Debian has dash for /bin/sh but not for interactive shells.

  5. henshaw

    Last time I read up on event designators I was scared off by the risk of executing the wrong command, like some of the other commenters.

    But there’s the histverify option which puts the expanded/edited history on the prompt (instead of executing it) so that you can check it’s sane.

  6. harri

    do you also know about !$ and !^ ? they repeat the last or first part of the last command.

    • rich

      Don’t forget !* too, which repeats the same arguments from the previous command:

      $ ls rpmbuild
      $ ls -l !*
      ls -l rpmbuild
      total 92
      drwxr-xr-x 132 rjones rjones  4096 2009-11-11 14:41 BUILD
      drwxr-xr-x  11 rjones rjones  4096 2009-11-11 14:41 BUILDROOT
      drwxr-xr-x   4 rjones rjones  4096 2009-05-16 22:20 RPMS
      drwxr-xr-x   2 rjones rjones 61440 2009-11-11 10:41 SOURCES
      drwxr-xr-x   2 rjones rjones  4096 2009-11-11 10:42 SPECS
      drwxr-xr-x   2 rjones rjones 12288 2009-11-11 14:41 SRPMS
  7. chris

    Oh yeah, using !, s/// etc are *so* much better than, you know, real command line editing via the readline library built into modern shells.

  8. juliobahar

    Interesting information… Thank you guys. One Question how does the Ctrl+R work?

  9. Another good one is the ![0-9]+.

    Say you want to re-run a long winded command that you ran ages ago.

    > history | grep longwinded
    1066 longwinded.sh multiple args
    longwinded.sh multiple args

    Of course, now that I’ve beed indoctrinated to Ctrl+R I would just Ctrl+R and do a command history search.

  10. Pingback: Cómo utilizar más eficazmente el historial de la terminal | Bitelia

  11. Craig Hughes

    Also !?somefoo which re-runs the last command that included “somefoo” somewhere in it. ie:

    > perform_something -a my_arg somefoo
    > …
    > …
    > !?somefoo
    [reruns perform_something -a my_arg somefoo]

  12. just a tiny little note:

    the !! appends to whatever you write, so if you forget to do a sudo before a command you can issue

    sudo !!

    and it appends the previous command after sudo.

    I also use CTRL-W and CTRL-U a lot, they erase a word or the entire line, respectively.

    I understand the comments about fearing these event designators, but in all honesty, it’s unix… where the difference between ./ and /. in a command can render your filesystem useless. It doesn’t require any more attention than anything else. and like anything else once you get into the groove of it, using it becomes a second nature.

  13. Richard

    I prefer to add these to my ~/.inputrc

    “\ep”: history-search-backward

    “\en”: history-search-forward

    That way alt-p and alt-n do the equivalent of !, but you get a preview to edit inline. e.g.

    $ ls -l /etc/resolv*
    $ vi /etc/resolv.conf
    $ l{Alt-p} == puts “ls -l /etc/resolv*” on the current line, with the cursor just after the l.

  14. @Allen Halsey et al 😉

    I have:

    $if Bash
    Space: magic-space

    in my ~/.inputrc file – this causes most/any of the expansions mentioned here to be auto-expanded when you press space; meaning you have a chance to check what may happen when you press Enter.

    Very useful 😉

  15. Pingback: Christmas gadgets: Comment utiliser plus efficacement l'historique du terminus

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.