From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11502 invoked from network); 6 Aug 2008 19:31:34 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.2.5 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 6 Aug 2008 19:31:34 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 36627 invoked from network); 6 Aug 2008 19:31:17 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 6 Aug 2008 19:31:17 -0000 Received: (qmail 2320 invoked by alias); 6 Aug 2008 19:31:08 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 25409 Received: (qmail 2288 invoked from network); 6 Aug 2008 19:31:04 -0000 Received: from bifrost.dotsrc.org (130.225.254.106) by sunsite.dk with SMTP; 6 Aug 2008 19:31:04 -0000 Received: from mtaout01-winn.ispmail.ntl.com (mtaout01-winn.ispmail.ntl.com [81.103.221.47]) by bifrost.dotsrc.org (Postfix) with ESMTP id 7E8F18056E06 for ; Wed, 6 Aug 2008 21:30:59 +0200 (CEST) Received: from aamtaout01-winn.ispmail.ntl.com ([81.103.221.35]) by mtaout01-winn.ispmail.ntl.com with ESMTP id <20080806193059.ZABF777.mtaout01-winn.ispmail.ntl.com@aamtaout01-winn.ispmail.ntl.com> for ; Wed, 6 Aug 2008 20:30:59 +0100 Received: from pws-pc ([81.107.40.67]) by aamtaout01-winn.ispmail.ntl.com with ESMTP id <20080806193059.TPGH5827.aamtaout01-winn.ispmail.ntl.com@pws-pc> for ; Wed, 6 Aug 2008 20:30:59 +0100 Date: Wed, 6 Aug 2008 20:30:55 +0100 From: Peter Stephenson 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) Message-ID: <20080806203055.3bc040af@pws-pc> In-Reply-To: <6cd6de210808041833me334c40ncc65835d8da4b5ba@mail.gmail.com> References: <6cd6de210808041833me334c40ncc65835d8da4b5ba@mail.gmail.com> X-Mailer: Claws Mail 3.5.0 (GTK+ 2.12.11; x86_64-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Virus-Scanned: ClamAV 0.92.1/7959/Wed Aug 6 15:06:37 2008 on bifrost X-Virus-Status: Clean On Mon, 4 Aug 2008 21:33:16 -0400 "Rocky Bernstein" 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 Web page now at http://homepage.ntlworld.com/p.w.stephenson/