25

Bash uses exclamation marks for history expansions, as explained in the answers to this question (e.g. sudo !! runs the previous command-line with sudo). However, I can't find anywhere that explains what running the following command (i.e. a single exclamation mark) does:

!

It appears to print nothing and exit with 1, but I'm not sure why it does that. I've looked online and in the Bash man page, but can't find anything, apart from the fact that it's a "reserved word" – but so is }, and running this:

}

prints an error:

bash: syntax error near unexpected token `}'
1
  • 1
    Nothing. ! indicates the "start" of a history expansion expression.
    – jordanm
    Apr 14, 2018 at 21:02

5 Answers 5

54

The lone ! at the start of a command negates the exit status of the command or pipeline: if the command exits 0, it will flip into 1 (failure), and if it exits non-zero it will turn it into a 0 (successful) exit.

This use is documented in the Bash manual:

If the reserved word ‘!’ precedes the pipeline, the exit status is the logical negation of the exit status as described above.

A ! with no following command negates the empty command, which does nothing and returns true (equivalent to the : command). It thus inverts the true to a false and exits with status 1, but produces no error.


There are also other uses of ! within the test and [[ commands, where they negate a conditional test. These are unrelated to what you're seeing. In both your question and those cases it's not related to history expansion and the ! is separated from any other terms.

1
  • 5
    +1 for the first answer to explain what is actually run and why that explains the return code.
    – Jeff Schaller
    Apr 14, 2018 at 23:56
13

You can find the single exclamation point documented in the bash manual section 3.2.2 Pipelines

If the reserved word ‘!’ precedes the pipeline, the exit status is the logical negation of the exit status as described above.

$ ! true; echo $?
1
$ ! false; echo $?
0

Also section 3.2.4.2 Conditional Constructs

! expression

True if expression is false.


Also section 4.1 Bourne Shell Builtins

! expr

True if expr is false.


It also should be noted that ! will start history substitution unless followed by: a space, tab, the end of the line, ‘=’ or ‘(’ (when the extglob shell option is enabled using the shopt builtin).

0
0

Because ! is used in comparisons and means NOT.

For example:

a=3
b=2

[ $a -eq $b ] && echo "Equal"
[ ! $a -eq $b ] && echo "Not equal"
# of cause last comparison is possible to write as:
[ $a -eq $b ] || echo "Not equal"

[ $a -eq $b ]
echo $?
1
[ ! $a -eq $b ]
echo $?
0
3
  • 1
    That's the meaning of ! as an argument to the test command (including bash's built-in version), not the meaning of ! when used in command position. Apr 14, 2018 at 21:40
  • 1
    It would need to be ! [...] to match the question in this case. Apr 14, 2018 at 21:41
  • Agreed with @Gilles and @Michael Homer. I knew that [] is test. I'm little hurried. Apr 14, 2018 at 21:48
-1

! built-in command, inverts the sense of a pipeline.

Other uses:

#! built-in command, invokes the named interpreter to execute the script.

! event designator, marks a command-line word as a history substitution

!= inequality operator

$! shell variable, returns process number of last background command.

1
  • Just to add, one can use !$ to use the last word of the previous command like so: ls -l /tmp cd !$ This will take you to the /tmp directory. Apr 18, 2018 at 2:11
-3

! followed by a string executes the most recent previous command (still in the command buffer) that started with the given string. Maybe the shell just found that no previous command began with <null>.

1
  • 3
    You noticed that there was no given string in the question...?
    – Jeff Schaller
    Apr 15, 2018 at 0:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .