In-Scope Pass Rate
93.23%
179 of 192 in-scope features
POSIX Shell Command Language compliance matrix for gbash.
This page tracks gbash conformance to the POSIX Shell Command Language as defined in XCU Chapter 2 of IEEE Std 1003.1-2024. It covers shell syntax, expansion, control flow, redirections, builtins, and variable semantics.
This is not a claim of formal POSIX certification. gbash targets practical compatibility with the shell command language for the features within its supported scope. Where POSIX and bash diverge, gbash generally follows bash unless its sandbox model requires otherwise.
errexit behaviorset -e, set -u, set -o pipefail, etc.)Each feature in the matrix below is classified as one of:
gbash documents its choicegbash supportsgbash deliberately omits itStatus is determined by:
This matrix catalogs gbash conformance to the POSIX Shell Command Language. All feature descriptions are original summaries derived from reading the specification requirements.
Generated April 9, 2026 at 8:19 AM. Reference: IEEE Std 1003.1-2024, XCU Chapter 2.
In-Scope Pass Rate
93.23%
179 of 192 in-scope features
Partial
16
features with incomplete coverage
Out of Scope
9
features excluded by sandbox model
Total Features
201
across 15 categories
Expand categories to inspect individual features. Green indicates full conformance, amber indicates partial support, red indicates a failure, and gray indicates features outside scope.
Counts shown as pass / partial / fail.
| Feature | Type | Status |
|---|---|---|
LEX-001Token boundary recognition at newlines and operatorsThe shell splits input into tokens at newline characters, operator characters, and whitespace boundaries following a defined precedence. | required | pass |
LEX-002Operator token recognitionMulti-character operators (&&, ||, <<, >>, etc.) are recognized as single tokens rather than sequences of single-character operators. | required | pass |
LEX-003Word formation from non-operator, non-delimiter charactersContiguous characters that are not operators or unquoted whitespace form a single word token. | required | pass |
LEX-004Comment recognition with leading hashA # character that is not quoted and appears where a new token could begin introduces a comment that extends to the next newline. | required | pass |
LEX-005Reserved word recognition in command positionWords like if, then, else, fi, do, done, case, esac, while, until, for, in, and function are recognized as reserved when they appear where a command name is expected. | required | pass |
LEX-006Reserved words not recognized mid-argumentA reserved word that appears as an argument to a command (not in command position) is treated as an ordinary word. | required | pass |
LEX-007Alias substitution before token recognitionWhen alias expansion is enabled, the shell replaces alias names with their definitions before further token processing. Alias expansion is off by default in non-interactive mode per POSIX. | required | pass |
LEX-008Recursive alias expansionIf an alias definition ends with a blank, the next word after the alias is also checked for alias substitution. Self-referencing aliases must not loop infinitely. Tricky edge case: alias a='b ' with alias b='a ' must terminate. | required | pass |
LEX-009IO_NUMBER token for redirection file descriptorsA sequence of digits immediately preceding a redirection operator (< or >) is recognized as a file descriptor number, not a word. | required | pass |
LEX-010Newline as command terminator and list separatorAn unquoted newline terminates the current command, functioning equivalently to a semicolon in most contexts. | required | pass |
LEX-011Line continuation with backslash-newlineA backslash immediately followed by a newline is removed, joining the next line to the current one before tokenization. | required | pass |
LEX-012Here-document token recognitionThe << and <<- operators are recognized as introducing here-documents. The delimiter word follows on the same line; the body extends to a line matching the delimiter exactly. | required | pass |
| Feature | Type | Status |
|---|---|---|
QUOT-001Backslash escaping of single charactersA backslash preserves the literal value of the following character, except when followed by a newline (which triggers line continuation). | required | pass |
QUOT-002Single quotes preserve all characters literallyCharacters enclosed in single quotes retain their literal meaning. No expansion or substitution occurs inside single quotes. | required | pass |
QUOT-003Double quotes allow parameter and command substitutionDouble quotes preserve literal values except for $, `, \, and !. Parameter expansion, command substitution, and arithmetic expansion are performed inside double quotes. | required | pass |
QUOT-004Backslash inside double quotesInside double quotes, backslash retains its escaping meaning only before $, `, \, ", and newline. Before other characters the backslash is preserved literally. | required | pass |
QUOT-005Dollar-single-quote ANSI-C escapingThe $'...' form interprets backslash escape sequences (\\n, \\t, \\xHH, \\uHHHH, etc.) within single quotes, producing the corresponding byte values. Added to POSIX in 2024 edition. Was previously a bash/ksh extension. | required | pass |
QUOT-006Dollar-double-quote locale translationThe $"..." form is intended for locale-dependent string translation. The shell may translate the enclosed string or treat it as a plain double-quoted string. gbash treats $\"...\" identically to \"...\". Most shells do the same in practice. | implementation defined | pass |
QUOT-007Quote removal as final expansion stepAfter all expansions, unquoted quote characters (single, double, backslash) that were not produced by expansion are removed from the final word. | required | pass |
QUOT-008Quoting prevents reserved word recognitionAny form of quoting (backslash, single quotes, double quotes) on any character of a reserved word prevents it from being recognized as reserved. | required | pass |
| Feature | Type | Status |
|---|---|---|
EXP-001Tilde expansion to home directoryAn unquoted tilde at the start of a word or after an unquoted colon in an assignment is replaced with the value of HOME (for bare ~) or the home directory of the named user (for ~user). gbash uses sandbox user metadata; ~user resolves within the sandbox. | required | pass |
EXP-002Tilde expansion in assignments after colonsIn variable assignments, tilde expansion also occurs after unquoted colons, enabling paths like PATH=~:~/bin to expand each tilde. | required | pass |
EXP-003Simple parameter expansion ($var and ${var})A dollar sign followed by a name or braced name is replaced with the variable's value, or the empty string if unset (unless nounset is active). | required | pass |
EXP-004Positional parameters ($1 through $9 and ${N})Shell parameters set from command-line arguments or function invocations are accessed as $1-$9 and ${10}, ${11}, etc. | required | pass |
EXP-005Special parameters ($@, $*, $#, $?, $$, $!, $0, $-)The shell provides read-only special parameters for argument lists, argument count, last exit status, shell PID, last background PID, invocation name, and current option flags. $$ and $! are virtual PIDs in gbash. | required | pass |
EXP-006"$@" preserves individual arguments in double quotesWhen "$@" is expanded inside double quotes, each positional parameter becomes a separate field, preserving argument boundaries. | required | pass |
EXP-007"$*" joins arguments with first character of IFSInside double quotes, "$*" expands to a single field with all positional parameters joined by the first character of IFS. | required | pass |
EXP-008Default value expansion ${var:-word} and ${var-word}Substitutes the expansion of word when var is unset (or unset/null with the colon form). The variable itself is not modified. | required | pass |
EXP-009Assign default ${var:=word} and ${var=word}Like default value, but also assigns the expanded word to var when the substitution triggers. | required | pass |
EXP-010Error if unset ${var:?word} and ${var?word}If var is unset (or unset/null with the colon form), the shell writes word to stderr and exits (in non-interactive shells). | required | pass |
EXP-011Alternate value ${var:+word} and ${var+word}Substitutes the expansion of word when var IS set (and non-null with the colon form). Returns empty otherwise. | required | pass |
EXP-012String length ${#var}Expands to the length in characters of the variable's value. | required | pass |
EXP-013Prefix removal ${var#pattern} and ${var##pattern}Removes the shortest (# form) or longest (## form) prefix matching the pattern from the variable's value. | required | pass |
EXP-014Suffix removal ${var%pattern} and ${var%%pattern}Removes the shortest (% form) or longest (%% form) suffix matching the pattern from the variable's value. | required | pass |
EXP-015Substring extraction ${var:offset:length}Extracts a substring starting at the given offset for the given length. Negative offsets count from the end (requires a space or parentheses to disambiguate from default-value syntax). Added in POSIX 2024. Negative offset edge cases differ across shells. | required | pass |
EXP-016Pattern substitution ${var/pattern/replacement}Replaces the first match of pattern in the variable's value with the replacement string. The // form replaces all matches. The /# and /% forms anchor to the start or end respectively. Added in POSIX 2024. Anchored forms are tested in OILS patsub tests. | required | pass |
EXP-017Case transformation ${var^}, ${var^^}, ${var,}, ${var,,}Converts the first character (^ or ,) or all characters (^^ or ,,) of the variable's value to uppercase or lowercase respectively. Added in POSIX 2024. | required | pass |
EXP-018Command substitution with $(command)Executes command in a subshell and replaces the construct with the command's standard output, with trailing newlines removed. | required | pass |
EXP-019Command substitution with backticksThe older `command` form performs the same substitution as $(command) but has different quoting rules for nested backslashes and backticks. Nested backtick quoting is a common edge-case source. | required | pass |
EXP-020Nested command substitutionThe $(...) form can be nested to arbitrary depth. Each level starts a new parsing context. | required | pass |
EXP-021Arithmetic expansion $((expression))The shell evaluates the arithmetic expression and replaces the construct with the decimal result. Standard integer operators (+, -, *, /, %, comparisons, bitwise, logical) are supported. | required | pass |
EXP-022Arithmetic variable references without $Inside arithmetic expressions, variable names are recognized and expanded without requiring a $ prefix. | required | pass |
EXP-023Arithmetic assignment operatorsArithmetic expressions support = and compound assignment operators (+=, -=, *=, /=, %=, <<=, >>=, &=, ^=, |=). | required | pass |
EXP-024Arithmetic ternary operatorThe expr ? expr : expr ternary conditional is supported in arithmetic expressions. | required | pass |
EXP-025Arithmetic comma operatorThe comma operator evaluates both operands and returns the value of the right operand. | required | pass |
EXP-026Arithmetic pre/post increment and decrementThe ++var, var++, --var, and var-- operators modify a variable and return the value before or after modification. Added in POSIX 2024. | required | pass |
EXP-027Arithmetic exponentiation operatorThe ** operator raises the left operand to the power of the right. Added in POSIX 2024. Right-associative. | required | pass |
EXP-028Expansion order (tilde, parameter, command, arith, field split, pathname, quote removal)Expansions are performed in a defined sequence. Tilde expansion first, then parameter/command/arithmetic in a single pass left-to-right, then field splitting, then pathname expansion, then quote removal. The ordering is a frequent source of subtle bugs across shells. | required | pass |
EXP-029Brace expansion {a,b,c} and {1..10}Brace expansion generates multiple words from comma-separated alternatives or numeric/alphabetic sequences. Not part of POSIX; originated in csh/bash. Bash extension. Controlled by set -B / set +B. | extension | pass |
EXP-030Process substitution <(cmd) and >(cmd)Process substitution connects a command's output or input to a file-like path that other commands can read from or write to. Bash/ksh extension. gbash implements this with sandbox-owned pipes. | extension | pass |
EXP-031Indirect expansion ${!var}Expands to the value of the variable whose name is stored in var. Bash extension. POSIX uses namerefs instead. | extension | pass |
EXP-032Expansion of $LINENO$LINENO expands to the current line number within the script or function being executed. | required | pass |
| Feature | Type | Status |
|---|---|---|
FSPLIT-001Field splitting on IFS whitespace charactersAfter expansion, unquoted results of parameter expansion, command substitution, and arithmetic expansion are split into fields at sequences of IFS whitespace characters (space, tab, newline by default). | required | pass |
FSPLIT-002IFS non-whitespace characters as field delimitersNon-whitespace characters in IFS act as explicit delimiters. Each occurrence produces a field boundary. Adjacent IFS non-whitespace characters produce empty fields between them. Common pitfall: IFS=: with value 'a::b' must produce three fields. | required | pass |
FSPLIT-003Empty IFS disables field splittingWhen IFS is set to the empty string, no field splitting occurs. The entire expansion result becomes a single field. | required | pass |
FSPLIT-004Unset IFS behaves as default (space/tab/newline)When IFS is unset, field splitting behaves as if IFS were set to space, tab, and newline. | required | pass |
FSPLIT-005Leading and trailing IFS whitespace trimmingSequences of IFS whitespace at the beginning or end of an expansion result do not produce empty leading or trailing fields. | required | pass |
FSPLIT-006Field splitting suppressed inside double quotesExpansions occurring within double quotes are not subject to field splitting (except "$@" which splits on argument boundaries). | required | pass |
FSPLIT-007IFS with mixed whitespace and non-whitespaceWhen IFS contains both whitespace and non-whitespace characters, IFS whitespace is trimmed around non-whitespace delimiters, and the non-whitespace character alone acts as the delimiter. Subtle interaction. IFS=' :' with ' a : b ' should produce [a, b]. | required | pass |
| Feature | Type | Status |
|---|---|---|
PNAME-001Asterisk * matches any stringAn unquoted * in a word matches any string of zero or more characters in filenames. | required | pass |
PNAME-002Question mark ? matches single characterAn unquoted ? matches exactly one character in filenames. | required | pass |
PNAME-003Bracket expression [abc] character class matchingBracket expressions match a single character from a set or range. Supports character ranges [a-z], negation [!abc] or [^abc], and named classes like [:alpha:]. | required | pass |
PNAME-004Dot files excluded from * and ? by defaultFilenames beginning with a period are not matched by * or ? unless the pattern also begins with a literal period. dotglob shopt overrides this behavior (bash extension). | required | pass |
PNAME-005Slash characters never matched by wildcardsA slash in a pathname can only be matched by a literal slash in the pattern, never by *, ?, or bracket expressions. | required | pass |
PNAME-006Pattern that matches no files expands to itselfWhen a glob pattern matches no files, the pattern word is left unchanged (unless nullglob or failglob are enabled). nullglob and failglob are bash extensions. | required | pass |
PNAME-007Pathname expansion disabled by set -f (noglob)When the noglob option is set, pathname expansion is not performed and glob characters are treated as literal. | required | pass |
PNAME-008Glob results sorted in collation orderPathnames generated by globbing are sorted according to the current locale's collation sequence. gbash uses deterministic UTF-8 sorting which may differ from locale-based collation in some edge cases. | required | partial |
PNAME-009Extended glob patterns ?(pat), *(pat), +(pat), @(pat), !(pat)When extglob is enabled, extended pattern matching operators allow matching zero-or-one, zero-or-more, one-or-more, exactly-one, or none of the given patterns. Bash/ksh extension enabled by shopt -s extglob. | extension | pass |
PNAME-010Recursive glob with ** (globstar)When globstar is enabled, ** in a pathname matches zero or more directories recursively. Bash extension enabled by shopt -s globstar. | extension | pass |
| Feature | Type | Status |
|---|---|---|
REDIR-001Input redirection with < fileOpens the named file for reading on stdin (fd 0) or the specified file descriptor. | required | pass |
REDIR-002Output redirection with > fileOpens the named file for writing on stdout (fd 1) or the specified file descriptor. Creates the file if it does not exist; truncates it if it does. | required | pass |
REDIR-003Append redirection with >> fileOpens the named file for appending on stdout or the specified file descriptor. Creates the file if it does not exist. | required | pass |
REDIR-004Noclobber protection with set -C and >|When the noclobber option is set, > fails if the target file exists and is a regular file. The >| operator overrides this protection. | required | pass |
REDIR-005Here-document << delimiterReads input until a line containing only the delimiter is found. If the delimiter is unquoted, parameter expansion, command substitution, and arithmetic expansion occur in the body. | required | pass |
REDIR-006Here-document with quoted delimiter (no expansion)When any part of the delimiter word is quoted, no expansion is performed in the here-document body. | required | pass |
REDIR-007Here-document tab stripping with <<-The <<- form strips leading tab characters from each line of the here-document body and from the closing delimiter line. | required | pass |
REDIR-008Here-string <<< wordProvides the expansion of word as stdin to a command, with a trailing newline appended. Bash/ksh/zsh extension, not in POSIX. | extension | pass |
REDIR-009Descriptor duplication with n>&m and n<&mDuplicates file descriptor m onto descriptor n. The >&m form is for output descriptors; <&m is for input descriptors. | required | pass |
REDIR-010Descriptor closing with n>&- and n<&-Closes file descriptor n. | required | pass |
REDIR-011Read-write redirection with <> fileOpens the named file for both reading and writing on the specified descriptor (default fd 0). | required | pass |
REDIR-012Multiple redirections on a single commandA command may have multiple redirections which are applied left-to-right before the command executes. | required | pass |
REDIR-013Redirection applied to compound commandsRedirections may be placed after compound commands (if, while, for, case, brace groups, subshells) and apply to all commands within the construct. | required | pass |
REDIR-014Named file descriptor allocation with {varname}> and {varname}<The shell allocates a file descriptor >= 10 and assigns the number to the named variable. Bash 4.1+ extension. | extension | pass |
| Feature | Type | Status |
|---|---|---|
SCMD-001Simple command execution with argument listA simple command is a sequence of variable assignments and redirections, optionally followed by a command name and arguments. The command name is looked up and executed. | required | pass |
SCMD-002Variable assignments as prefix to a commandVariable assignments preceding a command name are placed in the environment of that command only (temporary bindings). If the command is a special builtin, the assignments persist. temp-binding behavior has known xfails for edge cases. | required | pass |
SCMD-003Variable assignment without a command nameWhen a simple command has assignments but no command name, the assignments take effect in the current shell environment. | required | pass |
SCMD-004Command search order (special builtins, functions, builtins, PATH)The shell searches for commands in order: special builtins, shell functions, regular builtins, then external commands via PATH. gbash has no PATH-based external command search; all commands are registry-backed. | required | partial |
SCMD-005Command not found exits with status 127If a command cannot be found, the exit status is 127. | required | pass |
SCMD-006Command found but not executable exits with status 126If a command is found but cannot be executed (e.g., missing execute permission), the exit status is 126. Not applicable to gbash's registry model; all registered commands are executable. | required | not applicable |
SCMD-007Empty command (only redirections or assignments)A command consisting only of redirections applies them in the current environment. A command of only assignments sets variables in the current environment. | required | pass |
SCMD-008exec builtin replaces shell or applies redirectionsThe exec builtin with a command argument replaces the shell process. Without a command argument, redirections are applied to the current shell. exec with a command does not replace the process in gbash (no real exec). exec with redirections works. | required | partial |
| Feature | Type | Status |
|---|---|---|
PIPE-001Pipeline connects stdout of left command to stdin of rightThe | operator creates a pipeline where the standard output of the command on the left is connected to the standard input of the command on the right. | required | pass |
PIPE-002Pipeline exit status is the last command's exit statusThe exit status of a pipeline is the exit status of the last command in the pipeline. | required | pass |
PIPE-003Pipeline negation with ! prefixPrefixing a pipeline with ! inverts its exit status: zero becomes one, and non-zero becomes zero. | required | pass |
PIPE-004Pipefail option (set -o pipefail)When pipefail is set, the pipeline exit status is the rightmost command that exited with non-zero status, or zero if all succeeded. Added to POSIX in 2024. Was previously a bash extension. | required | pass |
PIPE-005PIPESTATUS array captures per-stage exit codesThe PIPESTATUS array variable contains the exit status of each command in the most recent pipeline. Bash extension. | extension | pass |
PIPE-006Sequential list with semicolon (cmd1 ; cmd2)Commands separated by ; are executed sequentially. The shell waits for each command to complete before starting the next. | required | pass |
PIPE-007AND list (cmd1 && cmd2)The right command executes only if the left command exits with status zero. | required | pass |
PIPE-008OR list (cmd1 || cmd2)The right command executes only if the left command exits with non-zero status. | required | pass |
PIPE-009Asynchronous list with & (background execution)A command terminated by & is executed asynchronously. The shell does not wait for it to complete and sets $! to its process ID. gbash supports basic background execution but with virtual PIDs and no job control. | required | partial |
PIPE-010Pipeline components execute in subshell environmentEach command in a pipeline may execute in a subshell. Variable assignments in pipeline stages do not affect the parent shell (unless lastpipe is enabled for the final stage). lastpipe support is a bash extension that gbash implements. | required | pass |
| Feature | Type | Status |
|---|---|---|
COMP-001if/then/elif/else/fi conditionalExecutes the then-body if the condition command list exits with status zero. Supports elif chains and a final else clause. | required | pass |
COMP-002while loop (while/do/done)Repeatedly executes the body while the condition command list exits with status zero. | required | pass |
COMP-003until loop (until/do/done)Repeatedly executes the body until the condition command list exits with status zero (opposite of while). | required | pass |
COMP-004for loop iterating over word listThe for var in word... form iterates over the expanded word list, assigning each word to the variable and executing the body. | required | pass |
COMP-005for loop without word list (iterates over positional parameters)The for var (without in) iterates over the positional parameters, equivalent to for var in \"$@\". | required | pass |
COMP-006C-style for loop for (( init; cond; step ))Arithmetic for loop that evaluates init once, tests cond before each iteration, and evaluates step after each iteration. Bash/ksh extension. | extension | pass |
COMP-007case/esac pattern matchingMatches a word against patterns and executes the corresponding command list for the first matching pattern. Patterns support shell wildcards. Multiple patterns per clause are separated by |. | required | pass |
COMP-008case fall-through with ;& and ;;&The ;& terminator falls through to the next clause's commands unconditionally. The ;;& terminator continues testing subsequent patterns. Added to POSIX in 2024. Previously a bash extension. | required | pass |
COMP-009Brace group { list; }Groups commands for execution in the current shell environment. Unlike a subshell, variable assignments and redirections persist. | required | pass |
COMP-010Subshell ( list )Executes the command list in a subshell environment. Variable changes, directory changes, and other state modifications do not affect the parent shell. gbash simulates subshells with state cloning, not fork. | required | pass |
COMP-011Arithmetic command (( expression ))Evaluates an arithmetic expression. Returns exit status 0 if the result is non-zero, and status 1 if the result is zero. Bash/ksh extension. | extension | pass |
COMP-012Conditional expression [[ expression ]]Extended test command with pattern matching (==), regex matching (=~), and logical operators (&&, ||, !) without the quoting pitfalls of the [ command. Bash/ksh extension. Not in POSIX (which uses test/[ only). | extension | pass |
COMP-013select loop for menu generationDisplays a numbered menu from a word list, reads the user's choice, and assigns the selected word to a variable. Bash/ksh extension. Limited utility in sandbox/non-interactive mode. | extension | pass |
COMP-014break and continue in loopsbreak exits the innermost (or Nth) enclosing loop. continue skips to the next iteration of the innermost (or Nth) enclosing loop. break/continue in loop conditions has a known xfail. | required | pass |
COMP-015Empty compound command bodiesWhether empty bodies in if/then/fi or while/do/done are accepted or rejected is not specified by POSIX. Bash accepts them. gbash has xfails for empty then/fi and empty do/done cases. | unspecified | partial |
| Feature | Type | Status |
|---|---|---|
FUNC-001Function definition with name() compound-commandDefines a shell function that can be invoked as a simple command. The body is any compound command (typically a brace group). | required | pass |
FUNC-002Function definition with function keywordThe function name { ... } syntax is an alternative way to define functions. Bash/ksh extension. | extension | pass |
FUNC-003Functions receive positional parameters from callerWhen a function is invoked, the arguments become the function's positional parameters. The caller's positional parameters are saved and restored when the function returns. | required | pass |
FUNC-004return builtin exits function with specified statusThe return builtin causes the function to exit with the given status (or the status of the last command if no argument). | required | pass |
FUNC-005Local variables with local/declare in functionsThe local builtin creates function-scoped variables that are destroyed when the function returns. POSIX does not require local variables but most shells support them. local is a bash extension. POSIX added it in 2024 as an XSI extension. | extension | pass |
FUNC-006Functions share the shell's execution environmentFunctions execute in the current shell environment (not a subshell). Variable assignments in a function are visible to the caller unless the variable is declared local. | required | pass |
FUNC-007Recursive function callsFunctions can call themselves recursively. Each invocation gets its own positional parameters. | required | pass |
FUNC-008Function names with special charactersPOSIX requires function names to be valid shell names. Whether names containing $, -, or other non-name characters are accepted is unspecified. Known xfails for function names with $ and command sub. | unspecified | partial |
| Feature | Type | Status |
|---|---|---|
BTIN-001Special builtins persist variable assignmentsVariable assignments preceding special builtins (break, :, ., continue, eval, exec, exit, export, readonly, return, set, shift, times, trap, unset) persist in the shell environment after the builtin completes. | required | pass |
BTIN-002Special builtin errors may cause non-interactive shell to exitCertain errors in special builtins (like a redirection error) may cause a non-interactive shell to exit, unlike regular builtins. gbash may not exit on all POSIX-required special-builtin errors. | required | partial |
BTIN-003colon (:) null commandThe : command does nothing and exits with status 0. Used for side effects of expansions in its arguments. | required | pass |
BTIN-004dot (.) source a script fileReads and executes commands from a file in the current shell environment. The file is searched for in PATH if not found by pathname. | required | pass |
BTIN-005eval concatenates and executes argumentsConcatenates all arguments with spaces and executes the result as a shell command in the current environment. | required | pass |
BTIN-006export marks variables for child environmentsMarks named variables to be included in the environment of subsequently executed commands. | required | pass |
BTIN-007readonly prevents variable modificationMarks named variables as readonly. Subsequent attempts to assign or unset them produce an error. Some readonly assignment edge cases have known xfails. | required | pass |
BTIN-008set modifies shell options and positional parametersWith option flags, enables or disables shell behaviors. With arguments after --, replaces positional parameters. Without arguments, lists all shell variables. | required | pass |
BTIN-009shift removes leading positional parametersShifts positional parameters by the specified count (default 1). $1 becomes the value of $(1+n), and $# decreases by n. | required | pass |
BTIN-010times displays accumulated process timesPrints accumulated user and system CPU times for the shell and its children. gbash reports synthetic times. Known xfail for format differences. | required | partial |
BTIN-011trap sets signal and event handlersAssociates a command string with a signal or pseudo-signal. When the signal arrives, the command is executed. Supports EXIT, ERR, DEBUG, and RETURN traps. | required | pass |
BTIN-012unset removes variables or functionsRemoves the named variable from the shell environment. With -f, removes the named function. Dynamic scoping with unset has known edge-case xfails. | required | pass |
BTIN-013exit terminates the shellExits the shell with the given status (or the status of the last command executed). EXIT traps are executed before termination. | required | pass |
BTIN-014test / [ conditional expression evaluationEvaluates a conditional expression and returns 0 (true) or 1 (false). Supports file tests, string tests, integer comparisons, and logical operators. | required | pass |
BTIN-015echo outputs argumentsWrites its arguments separated by spaces to stdout, followed by a newline. echo -n and -e behavior is implementation-defined in POSIX. gbash follows bash. | required | pass |
BTIN-016printf formatted outputFormats and prints arguments according to a format string, similar to C printf. Supports %s, %d, %o, %x, %f, %e, %g, %b, %q, etc. | required | pass |
BTIN-017read reads a line from stdinReads a line from standard input and splits it according to IFS into the named variables. The last variable receives the remainder. | required | pass |
BTIN-018cd changes working directoryChanges the current working directory. Supports -, CDPATH search, and -P (physical) vs -L (logical) path handling. | required | pass |
BTIN-019pwd prints working directoryPrints the absolute pathname of the current working directory. Supports -P (physical, no symlinks) and -L (logical, default). | required | pass |
BTIN-020type describes command typeIndicates how each argument would be interpreted as a command name (alias, function, builtin, file, or keyword). type -P and type -a have known xfails on Darwin. | required | pass |
BTIN-021command bypasses functionsExecutes a command bypassing shell function lookup. With -v, describes the command. With -p, searches only the default PATH. command -p has a known xfail (default PATH differs in sandbox). | required | partial |
BTIN-022getopts parses positional parametersParses option flags from positional parameters according to an option string. Sets OPTARG and OPTIND. | required | pass |
BTIN-023umask sets file creation maskGets or sets the file mode creation mask. Supports both symbolic and octal notation. | required | pass |
BTIN-024wait waits for background processesWaits for the specified process or job to complete and returns its exit status. Without arguments, waits for all background children. gbash wait works for virtual background jobs only. | required | partial |
BTIN-025kill sends signals to processesSends a signal (default SIGTERM) to the specified process IDs or job specifications. gbash kill only operates on virtual PIDs within the shell family. | required | partial |
BTIN-026hash remembers command locationsRemembers the locations of commands found via PATH search. With -r, clears the remembered locations. In gbash, all commands are registry-backed so hashing is a no-op concept. | required | pass |
BTIN-027declare/typeset sets variable attributesSets variable attributes such as integer (-i), readonly (-r), export (-x), lowercase (-l), uppercase (-u), array (-a), associative (-A), and nameref (-n). Bash extension. Core to bash scripting patterns. | extension | pass |
BTIN-028mapfile/readarray reads lines into arrayReads lines from stdin into an indexed array variable. Bash extension. | extension | pass |
BTIN-029let evaluates arithmetic expressionsEvaluates each argument as an arithmetic expression. Bash extension. | extension | pass |
BTIN-030enable enables or disables builtinsEnables or disables shell builtin commands by name. Bash extension. | extension | pass |
| Feature | Type | Status |
|---|---|---|
INVOC-001Shell reads commands from -c string argumentWhen invoked with -c, the shell reads commands from the provided string operand rather than from a file or stdin. | required | pass |
INVOC-002Shell reads commands from a script fileWhen invoked with a filename argument, the shell reads and executes commands from that file. | required | pass |
INVOC-003Shell reads from stdin when no file or -cIn interactive mode, the shell reads commands from standard input when no script file or -c string is provided. gbash is non-interactive by design; stdin reading is through the API. | required | not applicable |
INVOC-004errexit option (set -e)When set, the shell exits immediately if a simple command fails, unless the command is part of a condition (if, while, until, && / || chain, or negated with !). Numerous edge cases. Existing OILS tests cover many of them. | required | pass |
INVOC-005nounset option (set -u)When set, expanding an unset variable (other than $@ and $*) produces an error and causes the shell to exit. | required | pass |
INVOC-006verbose option (set -v)When set, the shell writes each input line to stderr before executing it. | required | pass |
INVOC-007xtrace option (set -x)When set, the shell writes each command to stderr (prefixed by the expansion of PS4) before execution. Known xfail for escape style of unprintable characters. | required | pass |
INVOC-008noexec option (set -n)When set, the shell reads commands but does not execute them. Used for syntax checking. | required | pass |
INVOC-009allexport option (set -a)When set, all variable assignments are automatically exported. | required | pass |
INVOC-010noclobber option (set -C)When set, output redirection with > fails if the file already exists and is a regular file. | required | pass |
| Feature | Type | Status |
|---|---|---|
EXIT-001Exit status 0 indicates successAn exit status of zero indicates the command completed successfully. | required | pass |
EXIT-002Exit status 1-125 indicate command-specific failuresNon-zero exit statuses from 1 to 125 indicate various command-defined error conditions. | required | pass |
EXIT-003Exit status 126 for permission deniedA command found but not executable (permission denied) should produce exit status 126. Not applicable to gbash registry model. | required | not applicable |
EXIT-004Exit status 127 for command not foundA command that cannot be found produces exit status 127. | required | pass |
EXIT-005Exit status > 128 for signal terminationWhen a command is terminated by a signal, the exit status is 128 plus the signal number. gbash implements this for trapped signals on virtual PIDs. | required | partial |
EXIT-006errexit interactions with compound commandsIn the context of errexit, failures in conditions of if/while/until, in commands negated with !, and in the left side of && or || do not trigger an immediate exit. Complex area. Tested extensively in OILS errexit tests. | required | pass |
EXIT-007$? reflects last command's exit statusThe $? special parameter always holds the exit status of the most recently completed foreground command or pipeline. | required | pass |
EXIT-008errtrace option (set -E) for ERR trap inheritanceWhen set, shell functions, command substitutions, and subshell environments inherit the ERR trap from the parent. Bash extension. | extension | pass |
EXIT-009Syntax errors cause non-interactive shell to exitA syntax error in a non-interactive shell causes it to exit with a non-zero status. | required | pass |
| Feature | Type | Status |
|---|---|---|
TRAP-001EXIT trap fires on shell exitA trap registered for EXIT is executed when the shell terminates, whether by reaching the end of input, executing exit, or receiving a fatal signal. | required | pass |
TRAP-002Signal traps (SIGINT, SIGTERM, etc.)The shell can register handlers for standard signals. When the signal is received, the handler command is executed. gbash routes signals through a virtual mechanism; not all signals are deliverable. | required | partial |
TRAP-003trap with no arguments lists active trapsInvoking trap without arguments outputs the currently set traps in a form suitable for re-evaluation. | required | pass |
TRAP-004trap '' SIGNAL ignores the signalSetting a trap action to the empty string causes the signal to be ignored. | required | pass |
TRAP-005trap - SIGNAL resets to defaultSetting a trap action to - resets the signal disposition to the default. | required | pass |
TRAP-006Traps inherited across subshellsWhen a subshell is created, traps that were set to be ignored are inherited. Traps set to a command string are reset to default in the subshell. | required | pass |
TRAP-007ERR trap fires on command failureThe ERR trap fires after any simple command exits with non-zero status, subject to errexit-like exemptions. Bash extension. | extension | pass |
TRAP-008DEBUG trap fires before each commandThe DEBUG trap fires before each simple command, for command, case command, and select command. Bash extension. | extension | pass |
TRAP-009RETURN trap fires on function/source returnThe RETURN trap fires each time a function or sourced script returns. Bash extension. | extension | pass |
TRAP-010Job control with bg, fg, jobsPOSIX job control allows suspending, resuming, and switching between foreground and background jobs using bg, fg, and jobs. gbash does not implement job control. No process suspension or TTY. | out of scope | not applicable |
TRAP-011Job control monitor mode (set -m)When monitor mode is enabled, the shell places each pipeline in its own process group and reports job completions. gbash does not implement process groups or job monitoring. | out of scope | not applicable |
TRAP-012Job specifications (%1, %%, %string)POSIX defines job specifications for referring to background jobs by number, by current/previous status, or by command prefix. gbash does not implement job specifications. | out of scope | not applicable |
TRAP-013SIGPIPE handling in pipelinesWhen a pipeline reader exits, writers should receive SIGPIPE and terminate rather than blocking or accumulating output. Known xfail for SIGPIPE regression test. | required | partial |
| Feature | Type | Status |
|---|---|---|
ENV-001Variable assignment with simple name=value syntaxVariables are assigned using name=value syntax. The value undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal. | required | pass |
ENV-002Append assignment with +=The += operator appends to an existing variable's value (or adds to an array). Bash extension. | extension | pass |
ENV-003Exported variables passed to child commandsVariables marked with export are included in the environment of all subsequently executed commands. | required | pass |
ENV-004Subshell inherits full variable environmentA subshell receives a copy of the parent's variables, functions, traps, and other state. Modifications in the subshell do not affect the parent. | required | pass |
ENV-005Temporary variable assignments for simple commandsVariable assignments before a command name are placed in the environment of that command only and do not persist (unless the command is a special builtin). Edge cases around temp bindings have known xfails in OILS tests. | required | pass |
ENV-006IFS variable controls field splittingThe IFS variable determines the characters used for field splitting after expansion and by the read builtin. | required | pass |
ENV-007PATH variable controls command searchThe PATH variable contains a colon-separated list of directories to search for external commands. gbash does not search PATH for host binaries. PATH is used for . (source) file lookup. | required | partial |
ENV-008HOME variable used for tilde expansionThe HOME variable's value is substituted for ~ in tilde expansion. | required | pass |
ENV-009PWD and OLDPWD track working directoryPWD holds the current working directory pathname. OLDPWD holds the previous working directory (set by cd). | required | pass |
ENV-010Indexed arraysBash-style indexed arrays with arr[i]=val syntax, ${arr[@]}, ${arr[*]}, ${#arr[@]}, and ${!arr[@]}. Bash extension. Core to many bash scripts. | extension | pass |
ENV-011Associative arraysAssociative arrays declared with declare -A, supporting arbitrary string keys. Bash extension. | extension | pass |
ENV-012Name references (declare -n)A nameref variable acts as an alias for another variable. Reading or assigning the nameref operates on the referenced variable. Bash 4.3+ extension. | extension | pass |
ENV-013RANDOM variable produces pseudo-random integersEach expansion of $RANDOM yields a pseudo-random integer between 0 and 32767. Assigning to RANDOM seeds the generator. Bash extension. gbash's RANDOM is seedable for deterministic replay. | extension | pass |
ENV-014SECONDS tracks elapsed timeSECONDS expands to the number of seconds since the shell started (or since last assigned). Bash extension. | extension | pass |
ENV-015Dynamic scoping for shell variablesShell variables use dynamic scoping in functions. A function sees the caller's variables unless local is used. Unset in dynamic scope reveals the previous scope's value. Multiple known xfails for dynamic-unset and tempenv interactions. | required | partial |
gbash is a sandbox-only runtime. Several POSIX requirements are fundamentally incompatible with this model. The table below catalogs every known deviation with rationale.
No real process model -- POSIX assumes fork/exec semantics. gbash uses Go goroutines and a command registry. Subshells are simulated via state cloning. $$, $BASHPID, and $PPID are virtual. exec with a command does not replace the process; exec with only redirections works normally.
No host filesystem -- gbash defaults to an in-memory virtual filesystem. Device files are limited to /dev/null, /dev/zero, /dev/stdin, /dev/stdout, /dev/stderr. No /proc or /sys. Symlink traversal is denied by default.
No job control -- bg, fg, jobs, disown, suspend are not available. set -m has no effect. Job specifications (%1, %%) are not supported. Background & works with virtual job IDs but jobs cannot be suspended or resumed.
No real signal delivery -- kill only sends to virtual PIDs within the shell family. Signal masking is not implemented. SIGPIPE behavior in pipelines may differ.
No TTY -- No stty, terminal capabilities, readline, or SIGWINCH. test -t returns false for sandbox descriptors.
Determinism over compatibility -- Glob results use deterministic UTF-8 sorting (may differ from locale collation). $RANDOM is seedable. Process IDs are stable and predictable.
Command-not-found -- gbash returns exit 127 for any command not in the registry. No host binary fallthrough.
Sandbox metadata -- uname, hostname, whoami, id return sandbox values. Environment inheritance is controlled. Output size, loop iterations, and substitution depth are bounded by policy.
Error messages -- Arithmetic errors, xtrace escaping, parse errors, and coreutils error messages may differ from bash's exact format.
Variable scoping -- Dynamic scoping with unset in nested functions, temporary bindings before builtins, and FUNCNAME substring operators have minor behavioral differences.
| ID | POSIX Requirement | gbash Behavior | Rationale |
|---|---|---|---|
| SCMD-004 | Search PATH for external commands | Registry lookup only | Sandbox: no host fallthrough |
| SCMD-006 | Exit 126 for permission denied | Not applicable | All registered commands are executable |
| SCMD-008 | exec replaces the shell | Redirections only | No real process replacement |
| PIPE-009 | Background & with real PIDs | Virtual job IDs | No fork/exec model |
| PNAME-008 | Glob sorted by locale collation | Deterministic UTF-8 sort | Determinism over locale |
| COMP-015 | Empty compound bodies | Partially accepted | Unspecified by POSIX |
| BTIN-002 | Special builtin errors exit shell | May not exit on all cases | Conservative error handling |
| BTIN-010 | times shows CPU times | Synthetic times | No process accounting |
| BTIN-021 | command -p uses default PATH | Sandbox PATH | No host PATH |
| BTIN-024 | wait for real PIDs | Virtual jobs only | No real PIDs |
| BTIN-025 | kill sends to real processes | Virtual PIDs only | Sandbox isolation |
| EXIT-005 | Exit > 128 for signal death | Trapped signals only | Virtual signal model |
| TRAP-002 | Signal handlers for all signals | Subset deliverable | Virtual mechanism |
| TRAP-010 | Job control (bg, fg, jobs) | Not implemented | Out of scope |
| TRAP-011 | Monitor mode (set -m) | No effect | Out of scope |
| TRAP-012 | Job specifications | Not implemented | Out of scope |
| TRAP-013 | SIGPIPE in pipelines | May differ | Virtual pipeline model |
| ENV-007 | PATH controls command search | Source file lookup only | Registry model |
| ENV-015 | Dynamic scoping with unset | Edge cases differ | Known limitation |