42

I'm following through a tutorial and it mentions to run this command:

sudo chmod 700 !$

I'm not familiar with !$. What does it mean?

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
Andrew
  • 623
  • 2
  • 6
  • 7
  • 5
    It's generally safe to try to `echo` something if you're not sure what it'll do. – Shadur Aug 29 '13 at 07:17
  • 10
    @Shadur, not always. `echo $(rm -rf /)` – cjm Aug 30 '13 at 03:20
  • 1
    @cjm Unless you're on a really old system, you'll need the `--no-preserve-root` option in there, and if you see the words "no preserve" in a program you better think real carefully about what it does. – wchargin Sep 02 '13 at 13:14
  • 4
    @WChargin Be very careful assuming that "really old" and "not Linux/not using GNU coreutils" are the same thing; they aren't. – Chris Down Nov 01 '13 at 08:31

3 Answers3

59

Basically, it's the last argument to the previous command.

!$ is the "end" of the previous command. Consider the following example: We start by looking for a word in a file:

grep -i joe /some/long/directory/structure/user-lists/list-15

if joe is in that userlist, we want to remove him from it. We can either fire up vi with that long directory tree as the argument, or as simply as vi !$ Which bash expands to:

vi /some/long/directory/structure/user-lists/list-15

(source; handy guide, by the way)


It's worth nothing the distinction between this !$ token and the special shell variable $_. Indeed, both expand to the last argument of the previous command. However, !$ is expanded during history expansion, while $_ is expanded during parameter expansion. One important consequence of this is that, when you use !$, the expanded command is saved in your history.

For example, consider the keystrokes

  • echo Foo Enter echo !$ Jar Enter Up Enter; and

  • echo Foo Enter echo $_ Jar Enter Up Enter.

(The only characters changed are the $! and $_ in the middle.)

In the former, when you press Up, the command line reads echo Foo Jar, so the last line written to stdout is Foo Jar.

In the latter, when you press Up, the command line reads echo $_ bar, but now $_ has a different value than it did previously—indeed, $_ is now Jar, so the last line written to stdout is Jar Jar.

Another consequence is that _ can be used in other parameter expansions, for example, the sequence of commands

printf '%s '    isomorphism
printf '%s\n'   ${_%morphism}sceles

prints isomorphism isosceles. But there's no analogous "${!$%morphism}" expansion.

For more information about the phases of expansion in Bash, see the EXPANSION section of man 1 bash (this is called Shell Expansions in the online edition). The HISTORY EXPANSION section is separate.

xhienne
  • 17,075
  • 2
  • 52
  • 68
wchargin
  • 1,071
  • 3
  • 13
  • 25
  • 8
    Nice. Good to know. Also, good thing there's Stack Exchange. It's hard to search Google for something like `!$` – Andrew Aug 29 '13 at 05:27
  • 5
    BTW, on the command line, you can insert the last argument of the previous command by `insert-last-argument`, usually bound to `M-.`. – choroba Aug 29 '13 at 06:25
  • 1
    @Andrew please remember to accept this if it answers your question. Accepting and upvoting rather than posting comments are how thanks are expressed on the SE network, see [here](http://meta.stackexchange.com/q/126180/203101) for the "official" stance. – terdon Aug 29 '13 at 11:18
  • 1
    @Andrew FYI, I searched Google for "bash bang dollar" and got decent results, including this link as the third listing. – wchargin Aug 29 '13 at 13:14
  • 1
    @terdon I tried to accept the answer last night, but it was so fast that I was forced to wait to accept it. – Andrew Aug 29 '13 at 14:36
  • *(The only characters changed are the `$!` and `$_` in the middle)*. I guess you meant `!$` instead of `$!` – GypsyCosmonaut Aug 12 '17 at 04:26
  • *prints `isomorphism isosceles`*. No, it prints `isosceles` – GypsyCosmonaut Aug 12 '17 at 04:32
  • 1
    @GypsyCosmonaut In fact, the sequence of two commands listed above does print `isomorphism isosceles`. Note that the running text reads, "the **sequence of commands** `[...]` prints…". – wchargin Aug 15 '17 at 05:06
  • @Andrew: this page was the first result to Googling "What does !$ do in Linux?" – Dan Dascalescu Jan 17 '19 at 00:30
5

Strictly speaking !$ is the last word of the last command from the history list.

word - A sequence of characters treated as a unit by the shell. Words may not include unquoted metacharacters.

metacharacter - A character that, when unquoted, separates words. A metacharacter is a blank or one of the following characters: ‘|’, ‘&’, ‘;’, ‘(’, ‘)’, ‘<’, or ‘>’

blank - A space or tab character.

Examples:

set -o history # enable command history
set -o histexpand # enable ! style history substitution

HISTSIZE=10

# save all lines on the history list    
HISTCONTROL=
HISTIGNORE=

date
echo !$ # prints date

date>/dev/null
echo !$ # prints /dev/null

echo a b c>/dev/null
echo !$ # prints /dev/null

HISTCONTROL=ignorespace # lines which begin with a space character are not saved in the history list
echo a b c
 echo d e f # space at the beginning
echo !$ # prints c
Evgeny Vereshchagin
  • 5,286
  • 4
  • 35
  • 43
  • see also: [Bash and its exclamation mark command, preview actual command before executing it?](http://unix.stackexchange.com/questions/206698/bash-and-its-exclamation-mark-command-preview-actual-command-before-executing-i/210943#210943) – Evgeny Vereshchagin Jul 10 '15 at 19:37
-3

!$ will give you last command used for that particular user....

you can also find the history of commands used earlier by using history command... try it out....

NOTE: For a particular user, all the commands used earlier will be stored under bash history file.

PersianGulf
  • 10,728
  • 8
  • 51
  • 78
karthik G
  • 101
  • 1