29

The install guide for ack suggests installing the ack script using this command:

curl http://beyondgrep.com/ack-2.14-single-file > ~/bin/ack && chmod 0755 !#:3 

I assume that the !#:3 at the end is some kind of back-reference, but what does it mean? Is there an equivalent in zsh? Google has not been helpful.

2 Answers2

33

This is a special syntax, expanded by bash. It also works for zsh.

According to the bash man page (section HISTORY EXPANSION), the pattern expands as following:

  • The event designator !# refers to the entire command line typed so far which is curl http://beyondgrep.com/ack-2.14-single-file > ~/bin/ack && chmod 0755
  • : splits between the event designator (this case the entire line) and the word designator (selects a sub-part)
  • the word designator 3 which selects the third word/argument (counting of words starts at zero), in this case ~/bin/ack.

The final command line (usually displayed before executed) is: curl http://beyondgrep.com/ack-2.14-single-file > ~/bin/ack && chmod 0755 ~/bin/ack.

For details, see the bash manual or very similar the zsh manual

jofel
  • 26,758
  • 8
    I can't help but wonder: who thought this feature would ever be a good idea? – Rhymoid Oct 15 '15 at 20:03
  • 3
    @Rhymoid, I don't use !# much, but !!, !$, !*, !sud:p and many others are all extremely useful and I use them all the time. Check out http://unix.stackexchange.com/a/67/135943 – Wildcard Oct 16 '15 at 05:37
11

In bash, it is history substitution (all history substitutions start with !). Specifically, !# means everything on the command line so far, and the addition ':3' means the third word (starting count at 0).

So, the above command translates !#:3 into ~/bin/ack.

heemayl
  • 56,300
Brian
  • 1,442
  • 1
  • 10
  • 13