zsh-workers
 help / color / mirror / code / Atom feed
From: Peter Stephenson <p.w.stephenson@ntlworld.com>
To: zsh-workers@sunsite.dk
Subject: Re: eval and resetting $? (Was Re: trap DEBUG + set -o DEBUG_BEFORE_CMD not setting $? nonzero in current CVS)
Date: Wed, 6 Aug 2008 20:30:55 +0100	[thread overview]
Message-ID: <20080806203055.3bc040af@pws-pc> (raw)
In-Reply-To: <6cd6de210808041833me334c40ncc65835d8da4b5ba@mail.gmail.com>

On Mon, 4 Aug 2008 21:33:16 -0400
"Rocky Bernstein" <rocky.bernstein@gmail.com> wrote:
> However when I use it I run into something else that looks like either
> a bug or at least something whose behavior should be documented. In
> the following program it feels like $? gets changed/reset? before eval
> is run:
> 
> #!/usr/local/bin/zsh -f
> cmd='print $?'
> fdsafsdsfa # Invalid command
> eval $cmd  # print $? works and so does
>                   # ./file-containing: print $?
> 
> print $? works because $? is expanded before print is run. And
> sourcing a file which contains the string I want to eval also works,
> so this gives me a workaround for this problem.
> 
> But somehow I think that a string writing that to a file and sourcing
> it should be equivalent to eval'ing the string.

I think you're right, and it would confuse me, too.  Although this is
explicit behaviour of the eval builtin, it's not tested in the test
suite, and as well as not being documented it's not standard shell
behaviour, so it's probably a bug.  I think nobody's happened
to look at the current status in the first command of an eval
before---if they had, it's hard to see them thinking "great! the status
has been reset! all's well with the world!"

It might be here to ensure that an eval with empty code sets the status
to zero; in many (all?) shells, eval of an empty string or anything
syntactically equivalent resets the status.  We don't want to change
that.  Luckily, the test for that is easy, and unambiguous---if you
follow through execution as far as execlist() you'll see that any time
the test I've added to eval is false, there's shell code to execute.

Index: Doc/Zsh/builtins.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v
retrieving revision 1.108
diff -u -r1.108 builtins.yo
--- Doc/Zsh/builtins.yo	10 Jun 2008 08:50:36 -0000	1.108
+++ Doc/Zsh/builtins.yo	6 Aug 2008 19:28:23 -0000
@@ -382,7 +382,10 @@
 cindex(evaluating arguments as commands)
 item(tt(eval) [ var(arg) ... ])(
 Read the arguments as input to the shell and execute the resulting
-command in the current shell process.
+command(s) in the current shell process.  The return status is the
+same as if the commands had been executed directly by the shell;
+if there are no var(args) or they contain no commands (i.e. are
+an empty string or whitespace) the return status is zero.
 )
 item(tt(exec) [ tt(-cl) ] [ tt(-a) var(argv0) ] var(simple command))(
 Replace the current shell with an external command rather than forking.
Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.200
diff -u -r1.200 builtin.c
--- Src/builtin.c	31 Jul 2008 08:44:20 -0000	1.200
+++ Src/builtin.c	6 Aug 2008 19:28:24 -0000
@@ -4717,17 +4717,19 @@
 
     prog = parse_string(zjoin(argv, ' ', 1));
     if (prog) {
-	lastval = 0;
-
-	execode(prog, 1, 0);
+	if (wc_code(*prog->prog) != WC_LIST) {
+	    /* No code to execute */
+	    lastval = 0;
+	} else {
+	    execode(prog, 1, 0);
 
-	if (errflag)
-	    lastval = errflag;
+	    if (errflag)
+		lastval = errflag;
+	}
     } else {
 	lastval = 1;
     }
 
-
     errflag = 0;
     scriptname = oscriptname;
     ineval = oineval;
Index: Test/.distfiles
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/.distfiles,v
retrieving revision 1.20
diff -u -r1.20 .distfiles
--- Test/.distfiles	18 Dec 2007 21:16:30 -0000	1.20
+++ Test/.distfiles	6 Aug 2008 19:28:24 -0000
@@ -11,6 +11,7 @@
 B02typeset.ztst
 B03print.ztst
 B04read.ztst
+B05eval.ztst
 C01arith.ztst
 C02cond.ztst
 C03traps.ztst
Index: Test/B05eval.ztst
===================================================================
RCS file: Test/B05eval.ztst
diff -N Test/B05eval.ztst
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Test/B05eval.ztst	6 Aug 2008 19:28:24 -0000
@@ -0,0 +1,34 @@
+# Tests for the eval builtin.
+# This is quite short; eval is widely tested throughout the test suite
+# and its basic behaviour is fairly straightforward.
+
+%prep
+
+  cmd='print $?'
+
+%test
+
+  false
+  eval $cmd
+0:eval retains value of $?
+>1
+
+  # no point getting worked up over what the error message is...
+  ./command_not_found 2>/dev/null
+  eval $cmd
+0:eval after command not found
+>127
+
+  # trick the test system
+  sp=
+  false
+  eval "
+  $sp
+  $sp
+  $sp
+  "
+0:eval with empty command resets the status
+
+  false
+  eval
+0:eval with empty command resets the status

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


      reply	other threads:[~2008-08-06 19:31 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-05  1:33 Rocky Bernstein
2008-08-06 19:30 ` Peter Stephenson [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080806203055.3bc040af@pws-pc \
    --to=p.w.stephenson@ntlworld.com \
    --cc=zsh-workers@sunsite.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).