diff --git a/gash/eval.scm b/gash/eval.scm index daace06..4b572d9 100644 --- a/gash/eval.scm +++ b/gash/eval.scm @@ -33,8 +33,10 @@ ;;; ;;; Code: -(define* (eval-word word #:key (output 'fields) (rhs-tildes? #f)) +(define* (eval-word word #:key (output 'fields) (rhs-tildes? #f) + (on-command-substitution noop)) (parameterize ((eval-cmd-sub (lambda (exps) + (on-command-substitution) (sh:substitute-command (lambda () (for-each eval-sh exps)))))) @@ -124,11 +126,15 @@ ((' cmd*s ..1) (apply sh:pipeline (map exp->thunk cmd*s))) ((' (names words) ..1) - (for-each (lambda (name word) - (setvar! name (eval-word word - #:output 'string - #:rhs-tildes? #t))) - names words)) + (let* ((command-substitution? #f) + (thunk (lambda () (set! command-substitution? #t)))) + (for-each (lambda (name word) + (setvar! name (eval-word word + #:output 'string + #:rhs-tildes? #t + #:on-command-substitution thunk))) + names words) + (unless command-substitution? (set-status! 0)))) ((' . sub-exps) (sh:subshell (exps->thunk sub-exps))) ((' test-exp sub-exps ..1) diff --git a/tests/assignments.org b/tests/assignments.org index bae3a05..d2a5106 100644 --- a/tests/assignments.org +++ b/tests/assignments.org @@ -106,3 +106,52 @@ #+begin_example bin:gash #+end_example + +* Assignments reset exit status +:script: +#+begin_src sh + set +e + false + x=foobar +#+end_src + +* Assigning exit status works +:script: +#+begin_src sh + set +e + false + x=$? + echo $x +#+end_src +:stdout: +#+begin_example + 1 +#+end_example + +* Assignments use command substitutions for exit status +:script: +#+begin_src sh + set +e + x=$(false) + echo $? + x=$(true) + echo $? +#+end_src +:stdout: +#+begin_example + 1 + 0 +#+end_example + +* Assignments update exit status on the fly +:script: +#+begin_src sh + set +e + false + x=$? y=$(true) z=$? + echo $x $z +#+end_src +:stdout: +#+begin_example + 1 0 +#+end_example