5

From the ack installation page (http://betterthangrep.com/install/) there is a one-liner installation with curl:

curl http://betterthangrep.com/ack-standalone > ~/bin/ack && chmod 0755 !#:3

I understand that it's getting the file from the website and saving it to ~/bin/ack, then setting permissions, but what does that last part ( !#:3 ) do ? (I do not recognize the syntax and Googling didn't yield any helpful results)

NullUserException
  • 83,810
  • 28
  • 209
  • 234
sampson-chen
  • 45,805
  • 12
  • 84
  • 81
  • 3
    I'm the maintainer of betterthangrep.com and I didn't even know what it did, except to know that it worked. Thanks for asking what I should have asked when someone submitted it to me. :) – Andy Lester Oct 14 '12 at 21:24
  • 1
    Please don't use salutations like ["Thanks in advance!"](http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be-removed-from-posts). And don't add them to other people's posts. – NullUserException Oct 26 '12 at 16:05

2 Answers2

6

See the section called HISTORY EXPANSION in man bash, particularly the Word Designators subsection. !#:3 refers to the third word of the pipe, which is (in your example) ~/bin/ack. In order, the words of the command are curl, 0; http://betterthangrep.com/ack-standalone, 1; >, 2; ~/bin/ack, 3; &&, 4; chmod, 5; 0755, 6; !#:3, 7. That is, !#:3 is a way to repeat the filename without using a separate variable or literal text.

Regarding the question about > and whitespace, note that > is a metacharacter, which man bash defines as a “character that, when unquoted, separates words. One of the following: | & ; ( ) < > space tab”. So whitespace does not affect whether > counts as a token. But note that in the following example, the first 3 is quoted so that bash doesn't interpret it as part of a 3> redirection. When the line was entered, bash echoed the expanded line and then executed it.

$ seq '3'>bbb;cat !#:3 !#:2 ccc; head !#:3 !#:8
seq '3'>bbb;cat bbb > ccc; head bbb ccc
==> bbb <==
1
2
3

==> ccc <==
1
2
3
James Waldby - jwpat7
  • 8,593
  • 2
  • 22
  • 37
3

!# means to execute the command typed so far, but you can specify a parameter with :n. :0 would be the first word (curl), :1 the second one (http...) and so on.

Birei
  • 35,723
  • 2
  • 77
  • 82