What does typing a single exclamation mark do in Bash?












20















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 `}'









share|improve this question




















  • 1





    Nothing. ! indicates the "start" of a history expansion expression.

    – jordanm
    Apr 14 '18 at 21:02
















20















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 `}'









share|improve this question




















  • 1





    Nothing. ! indicates the "start" of a history expansion expression.

    – jordanm
    Apr 14 '18 at 21:02














20












20








20


5






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 `}'









share|improve this question
















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 `}'






bash history-expansion exit-status






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 15 at 17:20









Weijun Zhou

1,479324




1,479324










asked Apr 14 '18 at 20:57









JoshJosh

293212




293212








  • 1





    Nothing. ! indicates the "start" of a history expansion expression.

    – jordanm
    Apr 14 '18 at 21:02














  • 1





    Nothing. ! indicates the "start" of a history expansion expression.

    – jordanm
    Apr 14 '18 at 21:02








1




1





Nothing. ! indicates the "start" of a history expansion expression.

– jordanm
Apr 14 '18 at 21:02





Nothing. ! indicates the "start" of a history expansion expression.

– jordanm
Apr 14 '18 at 21:02










5 Answers
5






active

oldest

votes


















46














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.






share|improve this answer



















  • 5





    +1 for the first answer to explain what is actually run and why that explains the return code.

    – Jeff Schaller
    Apr 14 '18 at 23:56



















10














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).






share|improve this answer

































    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





    share|improve this answer





















    • 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.

      – Gilles
      Apr 14 '18 at 21:40






    • 1





      It would need to be ! [...] to match the question in this case.

      – Michael Homer
      Apr 14 '18 at 21:41













    • Agreed with @Gilles and @Michael Homer. I knew that is test. I'm little hurried.

      – Yurij Goncharuk
      Apr 14 '18 at 21:48



















    -2














    ! 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.






    share|improve this answer
























    • 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.

      – Hopping Bunny
      Apr 18 '18 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>.






    share|improve this answer





















    • 3





      You noticed that there was no given string in the question...?

      – Jeff Schaller
      Apr 15 '18 at 0:20










    protected by Michael Homer Apr 16 '18 at 4:45



    Thank you for your interest in this question.
    Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



    Would you like to answer one of these unanswered questions instead?














    5 Answers
    5






    active

    oldest

    votes








    5 Answers
    5






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    46














    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.






    share|improve this answer



















    • 5





      +1 for the first answer to explain what is actually run and why that explains the return code.

      – Jeff Schaller
      Apr 14 '18 at 23:56
















    46














    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.






    share|improve this answer



















    • 5





      +1 for the first answer to explain what is actually run and why that explains the return code.

      – Jeff Schaller
      Apr 14 '18 at 23:56














    46












    46








    46







    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.






    share|improve this answer













    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.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Apr 14 '18 at 22:21









    Michael HomerMichael Homer

    49.4k8133172




    49.4k8133172








    • 5





      +1 for the first answer to explain what is actually run and why that explains the return code.

      – Jeff Schaller
      Apr 14 '18 at 23:56














    • 5





      +1 for the first answer to explain what is actually run and why that explains the return code.

      – Jeff Schaller
      Apr 14 '18 at 23:56








    5




    5





    +1 for the first answer to explain what is actually run and why that explains the return code.

    – Jeff Schaller
    Apr 14 '18 at 23:56





    +1 for the first answer to explain what is actually run and why that explains the return code.

    – Jeff Schaller
    Apr 14 '18 at 23:56













    10














    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).






    share|improve this answer






























      10














      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).






      share|improve this answer




























        10












        10








        10







        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).






        share|improve this answer















        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).







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Apr 15 '18 at 12:51

























        answered Apr 14 '18 at 21:04









        Jesse_bJesse_b

        13.2k23369




        13.2k23369























            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





            share|improve this answer





















            • 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.

              – Gilles
              Apr 14 '18 at 21:40






            • 1





              It would need to be ! [...] to match the question in this case.

              – Michael Homer
              Apr 14 '18 at 21:41













            • Agreed with @Gilles and @Michael Homer. I knew that is test. I'm little hurried.

              – Yurij Goncharuk
              Apr 14 '18 at 21:48
















            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





            share|improve this answer





















            • 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.

              – Gilles
              Apr 14 '18 at 21:40






            • 1





              It would need to be ! [...] to match the question in this case.

              – Michael Homer
              Apr 14 '18 at 21:41













            • Agreed with @Gilles and @Michael Homer. I knew that is test. I'm little hurried.

              – Yurij Goncharuk
              Apr 14 '18 at 21:48














            0












            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





            share|improve this answer















            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






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Apr 14 '18 at 21:46

























            answered Apr 14 '18 at 21:05









            Yurij GoncharukYurij Goncharuk

            2,3272622




            2,3272622








            • 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.

              – Gilles
              Apr 14 '18 at 21:40






            • 1





              It would need to be ! [...] to match the question in this case.

              – Michael Homer
              Apr 14 '18 at 21:41













            • Agreed with @Gilles and @Michael Homer. I knew that is test. I'm little hurried.

              – Yurij Goncharuk
              Apr 14 '18 at 21:48














            • 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.

              – Gilles
              Apr 14 '18 at 21:40






            • 1





              It would need to be ! [...] to match the question in this case.

              – Michael Homer
              Apr 14 '18 at 21:41













            • Agreed with @Gilles and @Michael Homer. I knew that is test. I'm little hurried.

              – Yurij Goncharuk
              Apr 14 '18 at 21:48








            1




            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.

            – Gilles
            Apr 14 '18 at 21:40





            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.

            – Gilles
            Apr 14 '18 at 21:40




            1




            1





            It would need to be ! [...] to match the question in this case.

            – Michael Homer
            Apr 14 '18 at 21:41







            It would need to be ! [...] to match the question in this case.

            – Michael Homer
            Apr 14 '18 at 21:41















            Agreed with @Gilles and @Michael Homer. I knew that is test. I'm little hurried.

            – Yurij Goncharuk
            Apr 14 '18 at 21:48





            Agreed with @Gilles and @Michael Homer. I knew that is test. I'm little hurried.

            – Yurij Goncharuk
            Apr 14 '18 at 21:48











            -2














            ! 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.






            share|improve this answer
























            • 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.

              – Hopping Bunny
              Apr 18 '18 at 2:11


















            -2














            ! 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.






            share|improve this answer
























            • 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.

              – Hopping Bunny
              Apr 18 '18 at 2:11
















            -2












            -2








            -2







            ! 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.






            share|improve this answer













            ! 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.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Apr 15 '18 at 0:04









            BharatBharat

            38111




            38111













            • 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.

              – Hopping Bunny
              Apr 18 '18 at 2:11





















            • 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.

              – Hopping Bunny
              Apr 18 '18 at 2:11



















            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.

            – Hopping Bunny
            Apr 18 '18 at 2:11







            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.

            – Hopping Bunny
            Apr 18 '18 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>.






            share|improve this answer





















            • 3





              You noticed that there was no given string in the question...?

              – Jeff Schaller
              Apr 15 '18 at 0:20
















            -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>.






            share|improve this answer





















            • 3





              You noticed that there was no given string in the question...?

              – Jeff Schaller
              Apr 15 '18 at 0:20














            -3












            -3








            -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>.






            share|improve this answer















            ! 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>.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Apr 16 '18 at 5:28









            Michael Homer

            49.4k8133172




            49.4k8133172










            answered Apr 14 '18 at 23:17









            pdelmontepdelmonte

            1




            1








            • 3





              You noticed that there was no given string in the question...?

              – Jeff Schaller
              Apr 15 '18 at 0:20














            • 3





              You noticed that there was no given string in the question...?

              – Jeff Schaller
              Apr 15 '18 at 0:20








            3




            3





            You noticed that there was no given string in the question...?

            – Jeff Schaller
            Apr 15 '18 at 0:20





            You noticed that there was no given string in the question...?

            – Jeff Schaller
            Apr 15 '18 at 0:20





            protected by Michael Homer Apr 16 '18 at 4:45



            Thank you for your interest in this question.
            Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



            Would you like to answer one of these unanswered questions instead?



            Popular posts from this blog

            How to make a Squid Proxy server?

            第一次世界大戦

            Touch on Surface Book