diff options
-rw-r--r-- | Doc/Zsh/builtins.yo | 5 | ||||
-rw-r--r-- | Src/builtin.c | 14 | ||||
-rw-r--r-- | Test/.distfiles | 1 | ||||
-rw-r--r-- | Test/B05eval.ztst | 34 |
4 files changed, 47 insertions, 7 deletions
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index d7e3526cb..bcd03be98 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -382,7 +382,10 @@ findex(eval) 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. diff --git a/Src/builtin.c b/Src/builtin.c index 99daf866b..e1378d901 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -4717,17 +4717,19 @@ bin_eval(UNUSED(char *nam), char **argv, UNUSED(Options ops), UNUSED(int func)) 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; diff --git a/Test/.distfiles b/Test/.distfiles index d79079696..6fd78491b 100644 --- a/Test/.distfiles +++ b/Test/.distfiles @@ -11,6 +11,7 @@ B01cd.ztst B02typeset.ztst B03print.ztst B04read.ztst +B05eval.ztst C01arith.ztst C02cond.ztst C03traps.ztst diff --git a/Test/B05eval.ztst b/Test/B05eval.ztst new file mode 100644 index 000000000..6427d6f2c --- /dev/null +++ b/Test/B05eval.ztst @@ -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 |