POSIX compliance
POSIX (Portable Operating System Interface) is a set of standards specified by the IEEE to ensure compatibility among Unix-like operating systems. It defines a standard operating system interface and environment, including command-line utilities, shell scripting, and system calls.
As of 2025, the latest version of POSIX is POSIX.1-2024. The requirements for shells are mainly documented in the Shell & Utilities volume. Yash-rs aims to comply with the POSIX standard, providing a consistent and portable environment for shell scripting and command execution.
The shell currently supports running shell scripts and basic interactive features in a POSIX-compliant manner. See the homepage for an overview of implemented features. Progress on POSIX conformance and feature implementation is tracked in GitHub Issues and the GitHub Project.
Many features of yash-rs are still under development, and some may not yet be fully compliant with the POSIX standard. Any non-conforming behavior is described in the Compatibility section of each feature’s documentation. These sections also clarify which aspects of the shell’s behavior are POSIX requirements and which are shell-specific extensions.
Maximizing POSIX compliance
Some behaviors of yash-rs prioritize convenience over POSIX compliance. The posixlycorrect option disables such features. When this option is set:
- The shell no longer refuses to exit because of suspended jobs when the
exitbuilt-in is executed or end-of-file is reached in an interactive shell. (See Suspended jobs.) - Extension built-ins are ignored (treated as non-existing), so the shell falls through to searching for an external utility with the same name.
This list may be expanded in the future as more features are added to the shell.
Writing portable scripts
Even when yash-rs conforms to POSIX, it also implements extensions that POSIX does not specify. Such extensions are convenient, but scripts that rely on them may not run on other shells. The portable option helps you catch this: when set, the shell rejects or ignores non-portable features so that you can verify a script uses only portable constructs.
Unlike posixlycorrect, which changes how the shell behaves to maximize POSIX conformance, portable does not alter the behavior of POSIX-conformant constructs. It only restricts the shell to features that are portable across POSIX-conforming shells, reporting an error or ignoring a feature when a non-portable construct is used. The two options are independent and can be combined.
When the portable option is set, the shell reacts to non-portable features in one of the ways described below. Each item links to the page that documents the feature in full, including the POSIX requirement behind the restriction and how to write the same thing portably.
Features that cause an error
The shell reports an error and does not run the construct:
- (Since 3.3.0) A non-portable escape sequence in a dollar-single-quoted string (
$'…'): the\E,\?,\u, and\Uescapes, the\c@control escape, and\xfollowed by more than two hexadecimal digits. - (Since 3.3.0) A reserved word that immediately follows a subshell or a redirection without a separator (for example, the
}in{ ( foo ) }). - (Since 3.3.0) A command name ending with a
:(for example,foo:), in a position where a reserved word would be recognized. The lone:(colon built-in) is not affected. - (Since 3.3.0) A parameter expansion that uses a length or switch modifier with special parameter
*or@(for example,${#*}), or a trim modifier with special parameter#,*, or@(for example,${*#word}). - (Since 3.3.0) An assignment whose variable name starts with a digit or contains a character other than ASCII letters, digits, and underscores (for example,
1st=foo). - (Since 3.3.3) An operand naming a variable whose name starts with a digit or contains a character other than ASCII letters, digits, and underscores (for example,
1st), given to theexport,getopts,read,readonly, ortypesetbuilt-in. - (Since 3.3.1) An array assignment (
name=(...)). - (Since 3.3.0) A
!immediately followed by a(at the beginning of a pipeline. - (Since 3.3.0) A
((at the beginning of a command, where the first(opens a subshell. - (Since 3.3.0) The
;;∧|terminators in case commands. - (Since 3.3.0) A
forloop variable name that is quoted, contains an expansion, starts with a digit, or contains a character other than ASCII letters, digits, and underscores (for example,for "i"). - (Since 3.3.0) A function name that is quoted, contains an expansion, starts with a digit, or contains a character other than ASCII letters, digits, and underscores (for example,
"foo"() { :; }). - (Since 3.3.0) A function name that is the same as a special built-in utility name (for example,
export). Other built-in names, such ascdandsource, are not affected. - (Since 3.3.1) Defining an alias with a name that contains a character other than ASCII letters, digits,
!,%,,,-,@, or_. - (Since 3.3.0) The redirection operators
>>|and<<<. - (Since 3.3.0) A word that would be recognized as a file descriptor specification, used as the target of a redirection (for example, the
1in< 1>file). - (Since 3.3.5) A shell option given to the
setbuilt-in or on the command line in a spelling POSIX does not specify (for example,set --errexit). Theportableoption itself is always accepted, so that it can be turned off again. - (Since 3.3.5) An argument to
-oor+owritten in the same argument as the option itself on the command line (for example,yash3 -oerrexit). - (Since 3.3.4) Executing an elective or extension built-in (for example,
typeset). - (Since 3.3.5) An option that POSIX does not specify, a long option, an option argument written in the same argument as the option name, or a combination of options POSIX does not allow, given to the
cd,command,exit,export,jobs,pwd,read,readonly,return,trap,ulimit, orunsetbuilt-in. - (Since 3.3.5) A number of operands that POSIX does not allow with the accompanying options, given to the
.,command,export,readonly,type, orunsetbuilt-in. - (Since 3.3.5) A non-portable way of specifying a signal or listing signals with the
killbuilt-in. - (Since 3.3.3) Making the
PWD,OLDPWD,OPTIND,OPTARG, orLINENOvariable read-only with thereadonlybuilt-in. - (Since 3.3.4) Executing the
.built-in under the namesource. - (Since 3.3.2) The increment and decrement operators (
++and--) in an arithmetic expression.
Features that trigger a warning
The shell prints a warning to the standard error and runs the construct anyway:
Features that are ignored
The shell silently proceeds as if the construct were absent:
- (Since 3.3.3) An environment variable inherited at shell startup whose name starts with a digit or contains a character other than ASCII letters, digits, and underscores.
The portable option is still under development, so these lists will be expanded as more checks are implemented.