10

I'm not talking about the UNIX shebang meant to give the path of an interpreter. In fact, the shebang has made it quite hard to google this question successfully...

I'm talking about bash expansion:

  • !! retrieves the immediately preceding command (akin to the up arrow, but more usable)
  • !$ retrieves the last word of the last command
  • !# appears to retrieve the current line

But what're actually useful uses of !#?

  • echo !# expands to echo echo
  • echo echo !# expands to echo echo echo echo
  • ls !# expands to ls ls.

All of which seem overwhelmingly pointless. All I know about the !# command is what I've learned from using it – I'm not certain that I know its true functionality.

Ari Sweedler
  • 807
  • 7
  • 25
  • 1
    It's documented [here](https://www.gnu.org/software/bash/manual/html_node/Event-Designators.html); it expands to "The entire command line typed so far.". – Keith Thompson Aug 16 '17 at 18:15
  • 1
    `man bash | grep '!#'` – Cyrus Aug 16 '17 at 18:15
  • @jdv, that is discussing `!#` as an interpreter directive, not as an event designator. – ryanpcmcquen Aug 16 '17 at 18:21
  • Oh, heh. I assumed it was a misreading of #!. My bad. –  Aug 16 '17 at 18:22
  • 3
    You've got two answers giving you the definition, but are you looking for examples of productive uses of `!#`? – Will Barnwell Aug 16 '17 at 18:22
  • I'll give myself a break for the occasional reading comprehension error given the quality of most new questions. –  Aug 16 '17 at 18:24
  • 1
    @WillBarnwell yes! I am. I really had two questions. 1) What's the use of this. And 2) I can't see a use for this... is this really all that `!#` does?? –– Question 2 has been answered beautifully: "Yes. this is, in fact, all that `!#` does." **However**, that makes me wanna know the answer to question 1 even more! – Ari Sweedler Aug 16 '17 at 18:42
  • 1
    @AriSweedler, ...history expansion is something that exists for backwards compatibility with a time before we had readline, and for the benefit of people who still have finger memory from that age. Turning it off (with `set +H`) is oft considered a good idea. – Charles Duffy Aug 16 '17 at 19:25
  • (BTW, inasmuch as this is about interactive use rather than software development -- as history expansion **is turned off by default** in scripts -- this question is a better fit for [SuperUser](https://superuser.com) or [unix.se] SE). – Charles Duffy Aug 16 '17 at 19:26

2 Answers2

6

As mentioned comments on the question and other answer(s), you can easily find the section of man bash:

!#     The entire command line typed so far.

What isn't made explicit by the man pages or other documentation and perhaps leading you your befuddlement to a useful use for !# is that bash event designators are meant to be used in combination with the word designators and modifiers (found just below event designators on the man page). The use cases also make more sense when chaining commands together with pipes, ; or &/&&

For example:

I could use the substitution modifier to run a script foo.sh against two inputs bar and baz:

$ ./foo.sh bar; !#:s/bar/baz/

expands to form:

./foo.sh bar; ./foo.sh baz;

Or an example from the Docs (R.I.P. Docs) reproduced below shows how to use the word selector :N to select the first argument to the command as typed so far and neatly cd into the just created directory:

$ mkdir backup_download_directory && cd !#:1
mkdir backup_download_directory && cd backup_download_directory

These examples are pretty trivial, but I hope they show how !# could really save somebody some serious redundant typing while crafting powerful one-liners.

Will Barnwell
  • 4,049
  • 21
  • 34
  • 1
    Ahh, I understand. The `!#` is an incomplete tool! It's the handles of a scissor without the blade. After reading [9.3.2](https://www.gnu.org/software/bash/manual/html_node/Word-Designators.html#Word-Designators) and [9.3.3](https://www.gnu.org/software/bash/manual/html_node/Modifiers.html#Modifier) the face that someone coded `!#` into existence makes a lot more sense. Thanks to @KeithThompson for linking in [9.3.1](https://www.gnu.org/software/bash/manual/html_node/Event-Designators.html), those were the reference guides I needed. And to you, @WillBarnwell, thanks for the full answer! – Ari Sweedler Aug 16 '17 at 19:50
  • Revisiting this nearly 6 years later, I can say that I use `!$` almost every day. Sometimes I'll use `!#`, too. One thing I did recently: rename a file inside a directory without having to type the dir path twice or cd: `mv /a/b/c/d.txt !#:1`. I am not using `:h` or anything more advanced like that... I am just using tab to expand (I use `zsh`). – Ari Sweedler Jun 21 '23 at 20:29
3

!# is The entire command line typed so far. From man bash:

Event Designators
   An event designator is a reference to a command line entry in the history list.

   !      Start a history substitution, except when followed by a blank, newline, carriage return,  =  or  (
          (when the extglob shell option is enabled using the shopt builtin).
   !n     Refer to command line n.
   !-n    Refer to the current command line minus n.
   !!     Refer to the previous command.  This is a synonym for `!-1'.
   !string
          Refer to the most recent command starting with string.
   !?string[?]
          Refer  to  the  most recent command containing string.  The trailing ? may be omitted if string is
          followed immediately by a newline.
   ^string1^string2^
          Quick substitution.  Repeat the last command,  replacing  string1  with  string2.   Equivalent  to
          ``!!:s/string1/string2/'' (see Modifiers below).
   !#     The entire command line typed so far.

One example of usage:

$ mkdir foo && cd !#:1

Makes the directory foo and changes to it.

ryanpcmcquen
  • 6,285
  • 3
  • 24
  • 37
  • Awesome! I mentioned how I was asking two questions in the comments to my original question, but this answers a third question that I had: "What are the other `!*` commands, and what do they do? Where can I find their documentation?" I shoulda known that it would be in the man page. And they're called "Event Designators". Thanks! :) – Ari Sweedler Aug 16 '17 at 18:47
  • 1
    @AriSweedler, I added one usage example. – ryanpcmcquen Aug 16 '17 at 19:14