682 lines
9.5 KiB
HTML
682 lines
9.5 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||
<HTML
|
||
><HEAD
|
||
><TITLE
|
||
>Exit and Exit Status</TITLE
|
||
><META
|
||
NAME="GENERATOR"
|
||
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
|
||
REL="HOME"
|
||
TITLE="Advanced Bash-Scripting Guide"
|
||
HREF="index.html"><LINK
|
||
REL="UP"
|
||
TITLE="Basics"
|
||
HREF="part2.html"><LINK
|
||
REL="PREVIOUS"
|
||
TITLE="Escaping"
|
||
HREF="escapingsection.html"><LINK
|
||
REL="NEXT"
|
||
TITLE="Tests"
|
||
HREF="tests.html"></HEAD
|
||
><BODY
|
||
CLASS="CHAPTER"
|
||
BGCOLOR="#FFFFFF"
|
||
TEXT="#000000"
|
||
LINK="#0000FF"
|
||
VLINK="#840084"
|
||
ALINK="#0000FF"
|
||
><DIV
|
||
CLASS="NAVHEADER"
|
||
><TABLE
|
||
SUMMARY="Header navigation table"
|
||
WIDTH="100%"
|
||
BORDER="0"
|
||
CELLPADDING="0"
|
||
CELLSPACING="0"
|
||
><TR
|
||
><TH
|
||
COLSPAN="3"
|
||
ALIGN="center"
|
||
>Advanced Bash-Scripting Guide: </TH
|
||
></TR
|
||
><TR
|
||
><TD
|
||
WIDTH="10%"
|
||
ALIGN="left"
|
||
VALIGN="bottom"
|
||
><A
|
||
HREF="escapingsection.html"
|
||
ACCESSKEY="P"
|
||
>Prev</A
|
||
></TD
|
||
><TD
|
||
WIDTH="80%"
|
||
ALIGN="center"
|
||
VALIGN="bottom"
|
||
></TD
|
||
><TD
|
||
WIDTH="10%"
|
||
ALIGN="right"
|
||
VALIGN="bottom"
|
||
><A
|
||
HREF="tests.html"
|
||
ACCESSKEY="N"
|
||
>Next</A
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
><HR
|
||
ALIGN="LEFT"
|
||
WIDTH="100%"></DIV
|
||
><DIV
|
||
CLASS="CHAPTER"
|
||
><H1
|
||
><A
|
||
NAME="EXIT-STATUS"
|
||
></A
|
||
>Chapter 6. Exit and Exit Status</H1
|
||
><TABLE
|
||
BORDER="0"
|
||
WIDTH="100%"
|
||
CELLSPACING="0"
|
||
CELLPADDING="0"
|
||
CLASS="EPIGRAPH"
|
||
><TR
|
||
><TD
|
||
WIDTH="45%"
|
||
> </TD
|
||
><TD
|
||
WIDTH="45%"
|
||
ALIGN="LEFT"
|
||
VALIGN="TOP"
|
||
><I
|
||
><P
|
||
><I
|
||
>... there are dark corners in the Bourne shell, and people use all
|
||
of them.</I
|
||
></P
|
||
><P
|
||
><I
|
||
>--Chet Ramey</I
|
||
></P
|
||
></I
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
><P
|
||
><A
|
||
NAME="EXITCOMMANDREF"
|
||
></A
|
||
>The
|
||
<B
|
||
CLASS="COMMAND"
|
||
>
|
||
|
||
exit
|
||
</B
|
||
>
|
||
command terminates a script, just as in a <B
|
||
CLASS="COMMAND"
|
||
>C</B
|
||
>
|
||
program. It can also return a value, which is available to the
|
||
script's parent process.</P
|
||
><P
|
||
><A
|
||
NAME="EXITSTATUSREF"
|
||
></A
|
||
>Every command returns an
|
||
<I
|
||
CLASS="FIRSTTERM"
|
||
>
|
||
exit status
|
||
</I
|
||
>
|
||
(sometimes referred to as a
|
||
<I
|
||
CLASS="FIRSTTERM"
|
||
>
|
||
return status
|
||
</I
|
||
> or <I
|
||
CLASS="FIRSTTERM"
|
||
>exit code</I
|
||
>).
|
||
<A
|
||
NAME="EXITSUCCESS"
|
||
></A
|
||
>
|
||
A successful command returns a <SPAN
|
||
CLASS="RETURNVALUE"
|
||
>0</SPAN
|
||
>, while
|
||
an unsuccessful one returns a <SPAN
|
||
CLASS="RETURNVALUE"
|
||
>non-zero</SPAN
|
||
>
|
||
value that usually can be interpreted as an <I
|
||
CLASS="FIRSTTERM"
|
||
>error
|
||
code</I
|
||
>. Well-behaved UNIX commands, programs, and
|
||
utilities return a <SPAN
|
||
CLASS="RETURNVALUE"
|
||
>0</SPAN
|
||
> exit code upon
|
||
successful completion, though there are some exceptions.</P
|
||
><P
|
||
><A
|
||
NAME="FUNCTXSTR"
|
||
></A
|
||
></P
|
||
><P
|
||
>Likewise, <A
|
||
HREF="functions.html#FUNCTIONREF"
|
||
>functions</A
|
||
>
|
||
within a script and the script itself return an exit
|
||
status. The last command executed in the function or
|
||
script determines the exit status. Within a script, an
|
||
<TT
|
||
CLASS="USERINPUT"
|
||
><B
|
||
>exit <TT
|
||
CLASS="REPLACEABLE"
|
||
><I
|
||
>nnn</I
|
||
></TT
|
||
></B
|
||
></TT
|
||
>
|
||
command may be used to deliver an
|
||
<SPAN
|
||
CLASS="RETURNVALUE"
|
||
><TT
|
||
CLASS="REPLACEABLE"
|
||
><I
|
||
>nnn</I
|
||
></TT
|
||
></SPAN
|
||
>
|
||
exit status to the shell
|
||
(<SPAN
|
||
CLASS="RETURNVALUE"
|
||
><TT
|
||
CLASS="REPLACEABLE"
|
||
><I
|
||
>nnn</I
|
||
></TT
|
||
></SPAN
|
||
>
|
||
must be an integer in the <SPAN
|
||
CLASS="RETURNVALUE"
|
||
>0</SPAN
|
||
> -
|
||
<SPAN
|
||
CLASS="RETURNVALUE"
|
||
>255</SPAN
|
||
> range).</P
|
||
><DIV
|
||
CLASS="NOTE"
|
||
><P
|
||
></P
|
||
><TABLE
|
||
CLASS="NOTE"
|
||
WIDTH="100%"
|
||
BORDER="0"
|
||
><TR
|
||
><TD
|
||
WIDTH="25"
|
||
ALIGN="CENTER"
|
||
VALIGN="TOP"
|
||
><IMG
|
||
SRC="../images/note.gif"
|
||
HSPACE="5"
|
||
ALT="Note"></TD
|
||
><TD
|
||
ALIGN="LEFT"
|
||
VALIGN="TOP"
|
||
><P
|
||
>When a script ends with an <B
|
||
CLASS="COMMAND"
|
||
>exit</B
|
||
> that has
|
||
no parameter, the exit status of the script is the exit status
|
||
of the last command executed in the script (previous to the
|
||
<B
|
||
CLASS="COMMAND"
|
||
>exit</B
|
||
>).</P
|
||
><P
|
||
><TABLE
|
||
BORDER="0"
|
||
BGCOLOR="#E0E0E0"
|
||
WIDTH="100%"
|
||
><TR
|
||
><TD
|
||
><FONT
|
||
COLOR="#000000"
|
||
><PRE
|
||
CLASS="PROGRAMLISTING"
|
||
>#!/bin/bash
|
||
|
||
COMMAND_1
|
||
|
||
. . .
|
||
|
||
COMMAND_LAST
|
||
|
||
# Will exit with status of last command.
|
||
|
||
exit</PRE
|
||
></FONT
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
></P
|
||
><P
|
||
>The equivalent of a bare <B
|
||
CLASS="COMMAND"
|
||
>exit</B
|
||
> is
|
||
<B
|
||
CLASS="COMMAND"
|
||
>exit $?</B
|
||
> or even just omitting the
|
||
<B
|
||
CLASS="COMMAND"
|
||
>exit</B
|
||
>.</P
|
||
><P
|
||
><TABLE
|
||
BORDER="0"
|
||
BGCOLOR="#E0E0E0"
|
||
WIDTH="100%"
|
||
><TR
|
||
><TD
|
||
><FONT
|
||
COLOR="#000000"
|
||
><PRE
|
||
CLASS="PROGRAMLISTING"
|
||
>#!/bin/bash
|
||
|
||
COMMAND_1
|
||
|
||
. . .
|
||
|
||
COMMAND_LAST
|
||
|
||
# Will exit with status of last command.
|
||
|
||
exit $?</PRE
|
||
></FONT
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
></P
|
||
><P
|
||
><TABLE
|
||
BORDER="0"
|
||
BGCOLOR="#E0E0E0"
|
||
WIDTH="100%"
|
||
><TR
|
||
><TD
|
||
><FONT
|
||
COLOR="#000000"
|
||
><PRE
|
||
CLASS="PROGRAMLISTING"
|
||
>#!/bin/bash
|
||
|
||
COMMAND1
|
||
|
||
. . .
|
||
|
||
COMMAND_LAST
|
||
|
||
# Will exit with status of last command.</PRE
|
||
></FONT
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
></P
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
></DIV
|
||
><P
|
||
><A
|
||
NAME="EXSREF"
|
||
></A
|
||
></P
|
||
><P
|
||
> <TT
|
||
CLASS="VARNAME"
|
||
> $?</TT
|
||
> reads the exit status of the last
|
||
command executed. After a function returns,
|
||
<TT
|
||
CLASS="VARNAME"
|
||
>$?</TT
|
||
> gives the exit status of the last
|
||
command executed in the function. This is Bash's way of giving
|
||
functions a <SPAN
|
||
CLASS="QUOTE"
|
||
>"return value."</SPAN
|
||
>
|
||
|
||
<A
|
||
NAME="AEN2981"
|
||
HREF="#FTN.AEN2981"
|
||
><SPAN
|
||
CLASS="footnote"
|
||
>[1]</SPAN
|
||
></A
|
||
>
|
||
</P
|
||
><P
|
||
><A
|
||
NAME="PIPEEX"
|
||
></A
|
||
>Following the execution of a <A
|
||
HREF="special-chars.html#PIPEREF"
|
||
>pipe</A
|
||
>, a <TT
|
||
CLASS="VARNAME"
|
||
>$?</TT
|
||
>
|
||
gives the exit status of the last command executed.</P
|
||
><P
|
||
>After a script terminates, a <TT
|
||
CLASS="VARNAME"
|
||
>$?</TT
|
||
> from the
|
||
command-line gives the exit status of the script, that is, the
|
||
last command executed in the script, which is, by convention,
|
||
<TT
|
||
CLASS="USERINPUT"
|
||
><B
|
||
>0</B
|
||
></TT
|
||
> on success or an integer in the
|
||
range <SPAN
|
||
CLASS="RETURNVALUE"
|
||
>1 - 255</SPAN
|
||
> on error.</P
|
||
><DIV
|
||
CLASS="EXAMPLE"
|
||
><A
|
||
NAME="EX5"
|
||
></A
|
||
><P
|
||
><B
|
||
>Example 6-1. exit / exit status</B
|
||
></P
|
||
><TABLE
|
||
BORDER="0"
|
||
BGCOLOR="#E0E0E0"
|
||
WIDTH="100%"
|
||
><TR
|
||
><TD
|
||
><FONT
|
||
COLOR="#000000"
|
||
><PRE
|
||
CLASS="PROGRAMLISTING"
|
||
>#!/bin/bash
|
||
|
||
echo hello
|
||
echo $? # Exit status 0 returned because command executed successfully.
|
||
|
||
lskdf # Unrecognized command.
|
||
echo $? # Non-zero exit status returned -- command failed to execute.
|
||
|
||
echo
|
||
|
||
exit 113 # Will return 113 to shell.
|
||
# To verify this, type "echo $?" after script terminates.
|
||
|
||
# By convention, an 'exit 0' indicates success,
|
||
#+ while a non-zero exit value means an error or anomalous condition.
|
||
# See the "Exit Codes With Special Meanings" appendix.</PRE
|
||
></FONT
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
></DIV
|
||
><P
|
||
><A
|
||
HREF="internalvariables.html#XSTATVARREF"
|
||
>$?</A
|
||
> is especially useful
|
||
for testing the result of a command in a script (see <A
|
||
HREF="filearchiv.html#FILECOMP"
|
||
>Example 16-35</A
|
||
> and <A
|
||
HREF="textproc.html#LOOKUP"
|
||
>Example 16-20</A
|
||
>).</P
|
||
><DIV
|
||
CLASS="NOTE"
|
||
><P
|
||
></P
|
||
><TABLE
|
||
CLASS="NOTE"
|
||
WIDTH="100%"
|
||
BORDER="0"
|
||
><TR
|
||
><TD
|
||
WIDTH="25"
|
||
ALIGN="CENTER"
|
||
VALIGN="TOP"
|
||
><IMG
|
||
SRC="../images/note.gif"
|
||
HSPACE="5"
|
||
ALT="Note"></TD
|
||
><TD
|
||
ALIGN="LEFT"
|
||
VALIGN="TOP"
|
||
><P
|
||
>The <A
|
||
HREF="special-chars.html#NOTREF"
|
||
>!</A
|
||
>, the <I
|
||
CLASS="FIRSTTERM"
|
||
>logical
|
||
not</I
|
||
> qualifier, reverses the outcome of a test or
|
||
command, and this affects its <A
|
||
HREF="exit-status.html#EXITSTATUSREF"
|
||
>exit
|
||
status</A
|
||
>.
|
||
|
||
<DIV
|
||
CLASS="EXAMPLE"
|
||
><A
|
||
NAME="NEGCOND"
|
||
></A
|
||
><P
|
||
><B
|
||
>Example 6-2. Negating a condition using <SPAN
|
||
CLASS="TOKEN"
|
||
>!</SPAN
|
||
></B
|
||
></P
|
||
><TABLE
|
||
BORDER="0"
|
||
BGCOLOR="#E0E0E0"
|
||
WIDTH="100%"
|
||
><TR
|
||
><TD
|
||
><FONT
|
||
COLOR="#000000"
|
||
><PRE
|
||
CLASS="PROGRAMLISTING"
|
||
>true # The "true" builtin.
|
||
echo "exit status of \"true\" = $?" # 0
|
||
|
||
! true
|
||
echo "exit status of \"! true\" = $?" # 1
|
||
# Note that the "!" needs a space between it and the command.
|
||
# !true leads to a "command not found" error
|
||
#
|
||
# The '!' operator prefixing a command invokes the Bash history mechanism.
|
||
|
||
true
|
||
!true
|
||
# No error this time, but no negation either.
|
||
# It just repeats the previous command (true).
|
||
|
||
|
||
# =========================================================== #
|
||
# Preceding a _pipe_ with ! inverts the exit status returned.
|
||
ls | bogus_command # bash: bogus_command: command not found
|
||
echo $? # 127
|
||
|
||
! ls | bogus_command # bash: bogus_command: command not found
|
||
echo $? # 0
|
||
# Note that the ! does not change the execution of the pipe.
|
||
# Only the exit status changes.
|
||
# =========================================================== #
|
||
|
||
# Thanks, St<53>phane Chazelas and Kristopher Newsome.</PRE
|
||
></FONT
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
></DIV
|
||
>
|
||
|
||
</P
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
></DIV
|
||
><DIV
|
||
CLASS="CAUTION"
|
||
><P
|
||
></P
|
||
><TABLE
|
||
CLASS="CAUTION"
|
||
WIDTH="100%"
|
||
BORDER="0"
|
||
><TR
|
||
><TD
|
||
WIDTH="25"
|
||
ALIGN="CENTER"
|
||
VALIGN="TOP"
|
||
><IMG
|
||
SRC="../images/caution.gif"
|
||
HSPACE="5"
|
||
ALT="Caution"></TD
|
||
><TD
|
||
ALIGN="LEFT"
|
||
VALIGN="TOP"
|
||
><P
|
||
>Certain exit status codes have <A
|
||
HREF="exitcodes.html#EXITCODESREF"
|
||
>reserved meanings</A
|
||
> and should not
|
||
be user-specified in a script. </P
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
></DIV
|
||
></DIV
|
||
><H3
|
||
CLASS="FOOTNOTES"
|
||
>Notes</H3
|
||
><TABLE
|
||
BORDER="0"
|
||
CLASS="FOOTNOTES"
|
||
WIDTH="100%"
|
||
><TR
|
||
><TD
|
||
ALIGN="LEFT"
|
||
VALIGN="TOP"
|
||
WIDTH="5%"
|
||
><A
|
||
NAME="FTN.AEN2981"
|
||
HREF="exit-status.html#AEN2981"
|
||
><SPAN
|
||
CLASS="footnote"
|
||
>[1]</SPAN
|
||
></A
|
||
></TD
|
||
><TD
|
||
ALIGN="LEFT"
|
||
VALIGN="TOP"
|
||
WIDTH="95%"
|
||
><P
|
||
>In those instances when there is no <A
|
||
HREF="complexfunct.html#RETURNREF"
|
||
>return</A
|
||
>
|
||
terminating the function.</P
|
||
></TD
|
||
></TR
|
||
></TABLE
|
||
><DIV
|
||
CLASS="NAVFOOTER"
|
||
><HR
|
||
ALIGN="LEFT"
|
||
WIDTH="100%"><TABLE
|
||
SUMMARY="Footer navigation table"
|
||
WIDTH="100%"
|
||
BORDER="0"
|
||
CELLPADDING="0"
|
||
CELLSPACING="0"
|
||
><TR
|
||
><TD
|
||
WIDTH="33%"
|
||
ALIGN="left"
|
||
VALIGN="top"
|
||
><A
|
||
HREF="escapingsection.html"
|
||
ACCESSKEY="P"
|
||
>Prev</A
|
||
></TD
|
||
><TD
|
||
WIDTH="34%"
|
||
ALIGN="center"
|
||
VALIGN="top"
|
||
><A
|
||
HREF="index.html"
|
||
ACCESSKEY="H"
|
||
>Home</A
|
||
></TD
|
||
><TD
|
||
WIDTH="33%"
|
||
ALIGN="right"
|
||
VALIGN="top"
|
||
><A
|
||
HREF="tests.html"
|
||
ACCESSKEY="N"
|
||
>Next</A
|
||
></TD
|
||
></TR
|
||
><TR
|
||
><TD
|
||
WIDTH="33%"
|
||
ALIGN="left"
|
||
VALIGN="top"
|
||
>Escaping</TD
|
||
><TD
|
||
WIDTH="34%"
|
||
ALIGN="center"
|
||
VALIGN="top"
|
||
><A
|
||
HREF="part2.html"
|
||
ACCESSKEY="U"
|
||
>Up</A
|
||
></TD
|
||
><TD
|
||
WIDTH="33%"
|
||
ALIGN="right"
|
||
VALIGN="top"
|
||
>Tests</TD
|
||
></TR
|
||
></TABLE
|
||
></DIV
|
||
></BODY
|
||
></HTML
|
||
> |