@@ -553,13 +553,17 @@ by redirection operators that are part of the command.
If the pipeline is not in the background (discussed later), the shell
waits for all commands to complete.
.Pp
-If the reserved word ! does not precede the pipeline, the exit status is
-the exit status of the last command specified in the pipeline.
-Otherwise, the exit status is the logical NOT of the exit status of the
-last command.
-That is, if the last command returns zero, the exit status
-is 1; if the last command returns greater than zero, the exit status is
-zero.
+If the
+.Em pipefail
+option was enabled when the shell began execution of the pipeline, the
+pipeline's exit status is the exit status of the last command specified in
+the pipeline that exited with non-zero status, or zero if all commands in
+the pipeline exited with a status of zero. If the
+.Em pipefail
+option was not enabled, the pipeline's exit status is the exit status of
+the last command specified in the pipeline; the exit statuses of any other
+commands are not used. If the reserved word ! precedes the pipeline, its
+exit status is the logical NOT of the exit status described above.
.Pp
Because pipeline assignment of standard input or standard output or both
takes place before redirection, it can be modified by redirection.
@@ -1791,6 +1795,19 @@ if the option is +o,
the settings are printed in a format suitable for
reinput to the shell to affect the same option settings.
.Pp
+In addition to the option names listed in the
+.Sx Argument List Processing
+section, the following options may be specified as arguments
+to -o or +o:
+.Bl -tag -width pipefail
+.It Em pipefail
+Derive the exit status of a pipeline from the exit statuses of all
+of the commands in the pipeline, not just the last command, as
+described in the
+.Sx Pipelines
+section.
+.El
+.Pp
The third use of the set command is to set the values of the shell's
positional parameters to the specified args.
To change the positional
@@ -1526,8 +1526,15 @@ STATIC int
getstatus(struct job *job) {
int status;
int retval;
+ struct procstat *ps;
+
+ ps = job->ps + job->nprocs - 1;
+ status = ps->status;
+ if (pipefail) {
+ while (status == 0 && --ps >= job->ps)
+ status = ps->status;
+ }
- status = job->ps[job->nprocs - 1].status;
retval = WEXITSTATUS(status);
if (!WIFEXITED(status)) {
#if JOBS
@@ -80,6 +80,7 @@ static const char *const optnames[NOPTS] = {
"notify",
"nounset",
"nolog",
+ "pipefail",
"debug",
};
@@ -101,6 +102,7 @@ const char optletters[NOPTS] = {
'u',
0,
0,
+ 0,
};
char optlist[NOPTS];
@@ -60,9 +60,10 @@ struct shparam {
#define bflag optlist[13]
#define uflag optlist[14]
#define nolog optlist[15]
-#define debug optlist[16]
+#define pipefail optlist[16]
+#define debug optlist[17]
-#define NOPTS 17
+#define NOPTS 18
extern const char optletters[NOPTS];
extern char optlist[NOPTS];