27

The question is pretty straight forward. I can get the exit code of the previous command by using $?. But what exactly is it?

I don't think it is a variable, because you can't have any special characters in the name of variable other than _.

foo?foo=10

will result in the error: foo?foo=10: command not found

So if it is not a variable, what is it? Are there others like it?

1

4 Answers 4

27

What is it?

$? is a built-in variable that stores the exit status of a command, function, or the script itself.

$? reads the exit status of the last command executed. After a function returns, $? gives the exit status of the last command executed in the function. This is Bash's way of giving functions a "return value." It returns 0 on success or an integer in the range 1 - 255 on error.

Are there others like it too?

Yes,there are several such built-in variables in bash. You can see a list here. Refer: http://www.tldp.org/LDP/abs/html/exit-status.html

3
  • 1
    So it's available in bash shell only? Jul 9, 2015 at 18:59
  • 4
    @daltonfury42 no, any shell that attempts to have some compatibility with the Bourne shell will support it (including dash, ksh, zsh, among others).
    – muru
    Jul 9, 2015 at 19:17
  • 2
    csh and fish use $status for the same purpose Jul 9, 2015 at 19:57
27

$? is a variable but a special one, that's why special characters are allowed. ($?) Expands to the exit status of the most recently executed foreground pipeline.

It's not the only one, the shell treats several parameters specially. These parameters may only be referenced; assignment to them is not allowed :

Variable    Meaning
$0          Filename of script
$1          Positional parameter #1
$2 - $9     Positional parameters #2 - #9
${10}       Positional parameter #10
$#          Number of positional parameters
"$*"        All the positional parameters (as a single word) *
"$@"        All the positional parameters (as separate strings)
${#*}       Number of positional parameters
${#@}       Number of positional parameters
$?          Return value
$$          Process ID (PID) of script
$-          Flags passed to script (using set)
$_          Last argument of previous command
$!          Process ID (PID) of last job run in background

* Must be quoted, otherwise it defaults to $@.

Sources:

5
  • 2
    "$*" is not just all positional parameters as a single word, but all positional parameters separated by the first character of IFS as a single word. Since the result will be subject to field splitting if not quoted, the effect is as if $@ is used in the unquoted case.
    – muru
    Jul 9, 2015 at 19:20
  • 1
    To be sure: unquoted $@ and $* are the same because they are both subject to word splitting. Quoted, "$@" preserves the word splitting of the positional parameters, even if an individual parameter contains a character in IFS.
    – kojiro
    Jul 10, 2015 at 3:26
  • 1
    Is there a reference of since when that is used for shells? I wonder if Perl took those from shell scripting.
    – simbabque
    Jul 10, 2015 at 11:47
  • This predates Perl by decades (or at least years). A lot of the Perl syntax was influenced by shell syntax. (Perl was born in 1987, and a lot of this syntax came from the original Bourne shell (1977). I'm not 100% when $_ was introduced, but it was almost certainly well before 1987.
    – Popup
    Jul 10, 2015 at 14:31
  • thank you, I have been find this comment for a long time... Nov 1, 2022 at 8:31
6

$? is a special variable in bash that always holds the return/exit code of the last executed command.

You can view it in a terminal by running echo $?.

Return codes are in the range [0; 255].
A return code of 0 usually means everything is ok.
Other values indicate errors. Most applications return 1 or custom values. If a command was not found, the variable usually contains 127

If you want to set this variable to a specific value, you can easily do this with bash -c "exit 5" to return for example the return code 5.

1
  • A shell function is a POSIX compliant way to set the exit status without necessarily forking. setstatus() { return 5; }
    – kojiro
    Jul 10, 2015 at 3:30
6

$? is a special shell parameter (variable).

In general all user defined variables must be named by using only the characters from character class [:alnum:] i.e. [a-zA-Z0-9_] (also can't begin with [0-9]).

In a nutshell, $? is a special variable (and there are quite a few of these) that can be considered as internal feature of the shell itself that provides the exit code of the previous command (whether succeded or failed).

You can read this to get more idea on variables.

Not the answer you're looking for? Browse other questions tagged or ask your own question.