POSIX mode
Start with cjsh --posix or invoke the executable with the name sh. The language
target is POSIX.1-2024 (Issue 8). This is a compatibility and extension-restriction
mode, not a claim of formal POSIX certification. Supplying POSIXLY_CORRECT alone
does not select it, and there is no runtime set -o posix switch.
cjsh --posix -eu -c 'printf "%s\n" "$1"' script-name argument
cjsh --posix -s -- argument < script.sh
cjsh --posix -n script.sh
In this mode, short invocation flags follow sh: -a, -b, -C, -e, -f,
-h, -m, -n, -u, -v, and -x set shell options; + clears them.
-o NAME and +o NAME select named options. -s reads commands from standard
input and passes remaining operands as positional parameters. -c uses the next
operand as its command string, followed by an optional $0 and positional
parameters. Native conveniences remain accessible through long options such as
--version, --help, --no-colors, --minimal, and --secure.
Supported standard features include tilde expansion (also in assignments),
$'…' quoting, pipefail, and case fall-through with ;&. These last three are
part of the 2024 standard. type is available as an XSI utility. set +o produces
commands that restore option state; set, export -p, and readonly -p quote
values for shell input. hashall and nolog accept their standardized settings;
they do not change cjsh's lookup or history implementation. The optional User
Portability Utilities vi line-editing option is not implemented.
notify (set -b) enables job notifications while waiting for interactive input.
Without it, background notifications wait until the next prompt. ignoreeof
requires exit to leave an interactive shell. Noninteractive background jobs do
not print interactive job notifications.
Noninteractive syntax, expansion, assignment, and special-builtin errors terminate
the current shell environment. Ordinary nonzero statuses remain ordinary command
results unless errexit applies. command removes a builtin's special status;
errors inside eval or a dot-sourced file still follow the rules of those commands.
Subshell errors remain isolated from the parent. Dot (.) searches PATH for
names without a slash, including readable files without execute permission.
Aliases expand before command operators are parsed, including chained aliases and
the next word after an alias ending in a blank. Function definitions retain the
aliases present when their bodies are read. A function body can be any supported
POSIX compound command; set -- and shift affect its arguments until it returns.
unset -f removes functions. read preserves the remaining separators in its
last variable and assigns partial input on EOF while returning failure. trap -p
prints restorable condition states, and an explicit exit in an exit trap selects
the final exit status.
The strict language policy rejects arrays, append assignments, arithmetic commands
(((…))), C-style for, select, the function keyword, [[…]], process
substitution, here-strings, |&, combined output redirections, ;;&, and cjsh's
auto-background operators. Parameter slicing, replacement, indirect expansion,
and case conversion are rejected. Brace expansion stays literal; extglob and
recursive globstar are disabled. Extension builtins and options such as source,
local, declare, read -n, test ==, and errexit_severity are unavailable.
Quoted text and here-document data retain their literal meaning.
Startup uses POSIX login profiles and interactive ENV; see the
startup rules. --no-config disables automatic
startup files for isolated script execution.
The dedicated tests run positive behavior, fatal errors, restrictions, builtin
semantics, and invocation options through both mode entry points. Script fixtures
run as command strings, files, standard input, eval, and dot sourcing. Separate
PTY tests exercise interactive error recovery, EOF handling, notification timing,
and retained wait statuses. Run them after building:
Expectations are based on the shell language,
sh, and
set
specifications. Passing the regression suite is not an exhaustive conformance assessment.