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.

  • 5
    Assuming bash; man bash, then search for HISTORY EXPANSION – Jeff Schaller Oct 15 '15 at 13:08
  • 1
    It means my cat walked across the keyboard at a really bad time. – IQAndreas Oct 16 '15 at 1:52
  • @IQAndreas: Well, it's a valid command, so your cat must be clever enough to defeat the cat typing detector.  Clearly this is not a useless cat.  :-)  ⁠ – G-Man Says 'Reinstate Monica' Oct 16 '15 at 5:27

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

  • 7
    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 unix.stackexchange.com/a/67/135943 – Wildcard Oct 16 '15 at 5:37

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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