name: "Builtins: eval" cases: - name: "Basic eval usage" stdin: | eval 'echo 1 + 1 == $((1 + 1))' - name: "eval with return in function" stdin: | f() { eval 'return 42' echo "Should not reach here" } f echo "Exit code: $?" - name: "eval with exit" stdin: | eval 'exit 42' echo "After eval'd exit" - name: "eval with break in loop" stdin: | for i in 1 2 3; do eval 'break' echo "After eval'd break" done echo "After loop" - name: "eval with continue in loop" stdin: | for i in 1 2 3; do echo "Iteration $i" eval 'continue' echo "After eval'd continue" done echo "After loop" - name: "eval with nested break levels" stdin: | for i in 1 2; do for j in a b c; do eval 'break 2' echo "After eval'd break (inner loop)" done echo "After eval'd break (outer loop)" done echo "After outer loop" - name: "Eval of code with syntax error" known_failure: true # TODO(eval): a tokenizer error in eval'd code aborts the script instead of returning 2 ignore_stderr: true stdin: | eval 'echo "a' echo "rc=$?" - name: "eval with a syntax error returns 2" known_failure: true # TODO(eval): a syntax error in eval's input ends a brush script ignore_stderr: true stdin: | eval 'if' echo "after eval: $?" - name: "eval with an unset variable under set -u ends the shell" ignore_stderr: true stdin: | set -u eval 'echo $nope'; echo "rc=$?" echo next - name: "eval with ${x?} on an unset variable ends the shell" ignore_stderr: true stdin: | eval 'echo ${nope?boom}'; echo "rc=$?" echo next - name: "command eval with an unset variable under set -u ends the shell" ignore_stderr: true stdin: | set -u command eval 'echo $nope'; echo "rc=$?" echo next - name: "builtin eval with an unset variable under set -u ends the shell" ignore_stderr: true stdin: | set -u builtin eval 'echo $nope'; echo "rc=$?" echo next - name: "eval passes the evaluated command's options through" stdin: | eval -- echo a eval echo -- b eval echo -n c; echo eval 'echo --help' - name: "eval rejects an unknown option with status 2" stdin: | eval -x 2>/dev/null; echo "rc=$?"