zsh-users
 help / color / mirror / code / Atom feed
* No pipefail option?
@ 2013-10-04 15:59 Shawn Halpenny
  2013-10-05 21:31 ` Peter Stephenson
  0 siblings, 1 reply; 2+ messages in thread
From: Shawn Halpenny @ 2013-10-04 15:59 UTC (permalink / raw)
  To: zsh-users

[-- Attachment #1: Type: text/plain, Size: 381 bytes --]

It seems like it would be a good bash-compatibility option to have
available.  I know we can check $pipestatus, but often I simply want to
abort the script if any command in the pipeline failed without having to do
an explicit check (similarly to how the errexit option works).  Explicit
checks too easily get forgotten or overlooked or even just implemented
incorrectly.

--Shawn

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: No pipefail option?
  2013-10-04 15:59 No pipefail option? Shawn Halpenny
@ 2013-10-05 21:31 ` Peter Stephenson
  0 siblings, 0 replies; 2+ messages in thread
From: Peter Stephenson @ 2013-10-05 21:31 UTC (permalink / raw)
  To: zsh-users

On Fri, 4 Oct 2013 08:59:49 -0700
Shawn Halpenny <paxunix@gmail.com> wrote:
> It seems like it would be a good bash-compatibility option to have
> available.  I know we can check $pipestatus, but often I simply want to
> abort the script if any command in the pipeline failed without having to do
> an explicit check (similarly to how the errexit option works).  Explicit
> checks too easily get forgotten or overlooked or even just implemented
> incorrectly.

It's not impossible it's this simple.

Indeed, if $pipestatus is working as advertised, it really ought to be
this simple...

diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo
index ec86232..71bddd5 100644
--- a/Doc/Zsh/options.yo
+++ b/Doc/Zsh/options.yo
@@ -1683,6 +1683,20 @@ Sequences of digits indicating a numeric base such as the `tt(08)'
 component in `tt(08#77)' are always interpreted as decimal, regardless
 of leading zeroes.
 )
+pindex(PIPE_FAIL)
+pindex(NO_PIPE_FAIL)
+pindex(PIPEFAIL)
+pindex(NOPIPEFAIL)
+cindex(exit status from pipeline)
+cindex(status, on exit from pipeline)
+cindex(pipeline, exit status from)
+itme(tt(PIPE_FAIL))(
+By default, when a pipeline exits the exit status recorded by the shell
+and returned by the shell variable tt($?) reflects that of the
+rightmost element of a pipeline.  If this option is set, the exit status
+instead reflects the status of the rightmost element of the pipeline
+that was non-zero, or zero if all elements exited with zero status.
+)
 pindex(SOURCE_TRACE)
 pindex(NO_SOURCE_TRACE)
 pindex(SOURCETRACE)
diff --git a/Src/jobs.c b/Src/jobs.c
index e1b24b2..b9d7a84 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -508,15 +508,22 @@ update_job(Job jn)
     jn->stat |= (somestopped) ? STAT_CHANGED | STAT_STOPPED :
 	STAT_CHANGED | STAT_DONE;
     if (job == thisjob && (jn->stat & STAT_DONE)) {
-	int i;
+	int i, newlastval = 0;
 	Process p;
 
-	for (p = jn->procs, i = 0; p && i < MAX_PIPESTATS; p = p->next, i++)
+	for (p = jn->procs, i = 0; p && i < MAX_PIPESTATS; p = p->next, i++) {
 	    pipestats[i] = ((WIFSIGNALED(p->status)) ?
 			    0200 | WTERMSIG(p->status) :
 			    WEXITSTATUS(p->status));
-	if ((jn->stat & STAT_CURSH) && i < MAX_PIPESTATS)
+	    if (pipestats[i])
+		newlastval = pipestats[i];
+	}
+	if ((jn->stat & STAT_CURSH) && i < MAX_PIPESTATS) {
 	    pipestats[i++] = lastval;
+	    if (!lastval && isset(PIPEFAIL))
+		lastval = newlastval;
+	} else if (isset(PIPEFAIL))
+	    lastval= newlastval;
 	numpipestats = i;
     }
     if (!inforeground &&
diff --git a/Src/options.c b/Src/options.c
index ad869b2..ce73d99 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -205,6 +205,7 @@ static struct optname optns[] = {
 {{NULL, "overstrike",	      0},			 OVERSTRIKE},
 {{NULL, "pathdirs",	      OPT_EMULATE},		 PATHDIRS},
 {{NULL, "pathscript",	      OPT_EMULATE|OPT_BOURNE},	 PATHSCRIPT},
+{{NULL, "pipefail",           OPT_EMULATE},              PIPEFAIL},
 {{NULL, "posixaliases",       OPT_EMULATE|OPT_BOURNE},	 POSIXALIASES},
 {{NULL, "posixbuiltins",      OPT_EMULATE|OPT_BOURNE},	 POSIXBUILTINS},
 {{NULL, "posixcd",            OPT_EMULATE|OPT_BOURNE},	 POSIXCD},
diff --git a/Src/zsh.h b/Src/zsh.h
index e6f0f65..a46898d 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -2121,6 +2121,7 @@ enum {
     OVERSTRIKE,
     PATHDIRS,
     PATHSCRIPT,
+    PIPEFAIL,
     POSIXALIASES,
     POSIXBUILTINS,
     POSIXCD,
diff --git a/Test/E01options.ztst b/Test/E01options.ztst
index bcb34c3..e00eb0e 100644
--- a/Test/E01options.ztst
+++ b/Test/E01options.ztst
@@ -1096,3 +1096,18 @@
 0:IGNORE_CLOSE_BRACES option
 >this is OK
 >6
+
+  (setopt pipefail
+  true | true | true
+  print $?
+  true | false | true
+  print $?
+  exit 2 | false | true
+  print $?
+  false | exit 2 | true
+  print $?)
+0:PIPE_FAIL option
+>0
+>1
+>1
+>2

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2013-10-05 21:38 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-04 15:59 No pipefail option? Shawn Halpenny
2013-10-05 21:31 ` Peter Stephenson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).