Files
sausage/userland/brush/source/brush-shell/tests/cases/compat/builtins/exec.yaml
T
2026-11-11 22:04:16 +00:00

134 lines
4.1 KiB
YAML

name: "Builtins: exec"
cases:
- name: "Exec an invalid path"
ignore_stderr: true
stdin: |
exec /some/nonexistent/path
- name: "Exec with no arguments"
stdin: |
pid=$$
exec
[[ "${pid}" == "$$" ]] || echo "PID changed"
- name: "Exec with no arguments and redirection for new fd"
stdin: |
exec 3>some-file.txt
echo "Hello, fd 3!" >&3
- name: "Exec with no arguments and redirection of stderr"
stdin: |
exec 2>/dev/null
# Do something that should display an error to stderr
source /non-existent
- name: "Exec with no arguments and redirection in a script"
test_files:
- path: "script.sh"
contents: |
exec 2>output-file.txt
echo hi >&2
args: ["./script.sh"]
- name: "Exec a command"
stdin: |
exec $0 -c 'echo "In child shell"'
echo "This is never reached"
- name: "exec without -c"
stdin: |
export myvar=value
exec $0 -c 'echo "myvar: ${myvar}"'
- name: "exec -c"
stdin: |
export myvar=value
exec -c $0 -c 'echo "myvar: ${myvar}"'
- name: "exec -a"
stdin: |
exec -a shellname $0 -c 'echo "0: $0"'
- name: "exec -c of a command found in the shell's PATH"
test_files:
- path: "bin/myscript"
executable: true
contents: |
#!/bin/sh
echo "in myscript"
stdin: |
PATH="${PWD}/bin:${PATH}"
exec -c myscript
echo "not reached"
- name: "exec of a missing command exits the shell"
known_failure: true # TODO(exec): a failed exec doesn't end a non-interactive shell
ignore_stderr: true
stdin: |
(exec nonexistent-command; echo "subshell still running: $?")
echo "subshell: $?"
exec /nonexistent-command
echo "still running: $?"
- name: "exec in a subshell ends the subshell"
known_failure: true # TODO(exec): exec in a subshell doesn't end the subshell
stdin: |
(exec true; echo "still running")
echo "true: $?"
(exec sh -c 'exit 3'; echo "still running")
echo "exit 3: $?"
(exec -a renamed sh -c 'echo "argv0: $0"')
(exec -l sh -c 'echo "login argv0: $0"')
echo hello | (exec cat; echo "still running")
- name: "exec in a subshell runs the program, not a builtin"
known_failure: true # TODO(exec): exec in a subshell runs a builtin of the same name instead
ignore_stderr: true
stdin: |
# The printf builtin would print nothing; the program prints "-v".
(exec printf -v out hi)
- name: "exec of a missing program reports it"
known_failure: true # TODO(exec): exec of a program that can't be found reports nothing at the top level
stdin: |
"$0" -c 'exec ./no-such-program' 2> err.txt
echo "status: $?"
[[ -s err.txt ]] && echo "reported" || echo "silent"
# (What it says has the test's directory in it, which differs between shells.)
rm err.txt
- name: "exec starts a program by its full path"
known_failure: true # TODO(exec): exec starts a program by the path it was found by, not its full path, so a script sees that as its $0
test_files:
- path: "sub/prog"
executable: true
contents: |
#!/bin/sh
echo "$0"
stdin: |
cd sub
started_by=$("$0" -c 'exec ./prog')
[[ ${started_by} == "${PWD}/prog" ]] && echo "full path" || echo "other: ${started_by}"
- name: "exec -a takes a name that starts with -"
stdin: |
exec -a -shellname $0 --noprofile -c 'echo "0: $0"'
- name: "exec passes the command's options through"
stdin: |
(exec -- echo a)
(exec echo -a b)
(exec echo -- c)
# A top-level exec replaces the shell with the program, so its arguments
# take the launch path rather than the builtin echo.
printf '#!/bin/sh\nprintf "[%%s]" "$@"; echo\n' > args; chmod +x args
"$0" --noprofile --norc -c 'exec -- ./args a'
"$0" --noprofile --norc -c 'exec ./args -a b'
"$0" --noprofile --norc -c 'exec ./args -- c'
rm args
- name: "exec rejects an unknown option with status 2"
stdin: |
(exec -x echo hi) 2>/dev/null; echo "rc=$?"