Since /bin/sh follows the POSIX standard quite closely, I think it would make sense to point out which features are non-POSIX and thus can not be safely assumed to be portable and exist in every shell implementation.
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Skipped - Unit
Tests Skipped
Event Timeline
| bin/sh/sh.1 | ||
|---|---|---|
| 86 | I suspect that in this case .St is not necessary? | |
| 325 | Just for the consistency. As I can see, man pages use 'non-standard' more often than 'nonstandard': $ grep -i 'nonstandard' $(find . -type f -name "*.[1-9]") |wc -l 15 $ grep -i 'non-standard' $(find . -type f -name "*.[1-9]") |wc -l 142 | |
| 1173 | I'm not sure that it is the best way to incorporate this information, but to me it seems quite natural, I think in cases where it can be done, it's better than a standalone sentence. | |
| 2819 | Maybe other suggestions how to write it better? | |
| bin/sh/sh.1 | ||
|---|---|---|
| 325 | wiktionary tells me nonstandard is more common in American English, non-standard is more common in British English. | |
| 1173 | "a non-standard local command" could be read as if there is a choice of local commands, one standard and one non-standard. "the non-standard local command" seems OK to me. | |
| bin/sh/sh.1 | ||
|---|---|---|
| 325 | Alright, according to this guideline, we should prefer American English variant. I would change 'behaviour' to 'behavior' then too. | |
Grammar improvements:
- Prefer American English: 'non-standard' -> 'nonstandard', 'behaviour' -> 'behavior'.
- 'a nonstandard local command' -> 'the nonstandard local command'.
I absolutely love the base premise of what you're trying to do here. This will be a major accessibility win for the faction which supports promoting portable programming, which FreeBSD is one of the main champions of.
Standard means too many different things in too many different contexts. The term "non-posix" seems popular:
$ git grep -i "non-posix" bin/sh/tests/builtins/local1.0:# A commonly used but non-POSIX builtin. bin/sh/tests/execution/shellproc7.0:# Non-POSIX trickery that is widely supported, cddl/contrib/opensolaris/head/synch.h: * non-posix symbols/constants violating the namespace restrictions. Hence, contrib/bc/gen/bc_help.txt: Error if any non-POSIX extensions are used. contrib/bc/gen/bc_help.txt: Warn if any non-POSIX extensions are used. contrib/bc/gen/bc_help.txt: Error if any non-POSIX extensions are used. contrib/bc/include/status.h: /// Non-POSIX comment used error. contrib/bc/include/status.h: /// Non-POSIX keyword error. contrib/bc/include/status.h: /// Non-POSIX . (last) error. contrib/bc/include/status.h: /// Non-POSIX return error. contrib/bc/include/status.h: /// Non-POSIX boolean operator used error. contrib/bc/include/status.h: /// Non-POSIX exponential (scientific or engineering) number used error. contrib/bc/include/status.h: /// Non-POSIX array reference error. contrib/bc/include/status.h: /// Non-POSIX void error. contrib/bc/include/status.h: /// Non-POSIX brace position used error. contrib/bc/src/bc_lex.c: // ensure that only non-POSIX keywords get redefined. contrib/bc/src/bc_parse.c: // If we are allowed non-POSIX stuff... contrib/byacc/CHANGES: relied upon non-POSIX behavior. contrib/byacc/CHANGES: use sed to work around non-POSIX tail utility contrib/byacc/aclocal.m4:dnl without losing the common non-POSIX features. contrib/dialog/CHANGES: + use $SHELL consistently, deprecate non-POSIX shell contrib/dialog/aclocal.m4:dnl without losing the common non-POSIX features. contrib/diff/ChangeLog: The following changes simplify porting to non-Posix environments. contrib/diff/NEWS:* New diff option: --binary (useful only on non-POSIX hosts) contrib/elftoolchain/nm/nm.c: * In non-POSIX mode, the option is a synonym for the '-A' and contrib/flex/ChangeLog: reformat a list of non-posix features contrib/libarchive/NEWS:Jan 30, 2008: Ignore hardlink size for non-POSIX tar archives. contrib/libarchive/libarchive/archive_read_support_format_tar.c: a->archive.archive_format_name = "tar (non-POSIX)"; contrib/libarchive/libarchive/archive_write_set_format_v7tar.c: a->format_name = "tar (non-POSIX)"; contrib/libarchive/libarchive/archive_write_set_format_v7tar.c: a->archive.archive_format_name = "tar (non-POSIX)"; contrib/libevent/configure:# libraries is broken (non-POSIX). contrib/libevent/m4/acx_pthread.m4:# libraries is broken (non-POSIX). contrib/libpcap/ftmacros.h: * to make non-POSIX APIs that we use unavailable. contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_checks.h:// and a bit relaxed requirement for non-POSIX ones, that the size is a multiple contrib/llvm-project/llvm/lib/Support/StringRef.cpp:// strncasecmp() is not available on non-POSIX systems, so define an contrib/lua/doc/manual.html:On non-POSIX systems, contrib/lua/doc/manual.html:On non-POSIX systems, contrib/ncurses/NEWS: + modify configure script to avoid conflict with a non-POSIX feature contrib/ncurses/NEWS: + build-fix for Solaris, whose /bin/sh and /usr/bin/sed are non-POSIX. contrib/ncurses/NEWS: non-POSIX systems (discussion with Stanislav Ievlev). contrib/ncurses/aclocal.m4:dnl a few others (i.e., GNU make and the non-POSIX "BSD" make): contrib/ncurses/aclocal.m4:dnl without losing the common non-POSIX features. contrib/ncurses/doc/hackguide.doc: This modules assist in POSIX emulation on non-POSIX systems: contrib/ncurses/ncurses/SigAction.h: * This file exists to handle non-POSIX systems which don't have <unistd.h>, contrib/ntp/sntp/libevent/configure:# libraries is broken (non-POSIX). contrib/ntp/sntp/libevent/m4/acx_pthread.m4:# libraries is broken (non-POSIX). contrib/ntp/sntp/m4/openldap.m4:[AC_CACHE_CHECK([non-posix strerror_r],ol_cv_nonposix_strerror_r,[ contrib/sendmail/RELEASE_NOTES: On some non-Posix systems, the decision of whether chown(2) permits contrib/sendmail/src/conf.c:** SETSID -- set session id (for non-POSIX systems) contrib/tcpdump/ftmacros.h: * to make non-POSIX APIs that we use unavailable. contrib/tcsh/tcsh.man:the test will succeed in a POSIX shell but fail in a non-POSIX shell. contrib/tcsh/tcsh.man.new:the test will succeed in a POSIX shell but fail in a non-POSIX shell. contrib/tzcode/NEWS: non-POSIX hosts where malloc doesn't set errno. contrib/tzdata/NEWS: -DHAVE_STRUCT_TIMESPEC=0 port to non-POSIX.1-2008 platforms contrib/tzdata/NEWS: non-POSIX hosts where malloc doesn't set errno. contrib/unbound/ax_pthread.m4:# libraries is broken (non-POSIX). contrib/unbound/configure:# libraries is broken (non-POSIX). contrib/xz/ChangeLog: and aren't needed on non-POSIX systems. contrib/xz/src/xz/util.h:/// This function exists, because non-POSIX systems don't support thousand contrib/xz/src/xz/xz.1:This feature is not available on non-POSIX systems. crypto/krb5/src/config/ac-archive/ax_pthread.m4:# libraries is broken (non-POSIX). crypto/krb5/src/configure:# libraries is broken (non-POSIX). crypto/openssh/openbsd-compat/fnmatch.c: * Notably, non-POSIX locales with FNM_CASEFOLD produce undefined results, crypto/openssh/openbsd-compat/fnmatch.c: * and non-POSIX locale collation orders; requires mbr* APIs to track shift crypto/openssh/openbsd-compat/sigact.h: * This file exists to handle non-POSIX systems which don't have <unistd.h>, include/pthread_np.h: * Non-POSIX thread function prototype definitions: include/xlocale/_wchar.h: * Only declare the non-POSIX functions if we're included from xlocale.h. lib/libc/locale/collate.c: * In the non-POSIX case, we transform each character into a string of lib/libc/posix1e/acl_get.c: * acl_get_fd_np - syscall wrapper for retrieving ACL by fd (non-POSIX) lib/libc/posix1e/acl_get.c: * (non-POSIX) lib/libc/posix1e/acl_get.c: * permset (non-POSIX) lib/libc/posix1e/acl_to_text.c: * a non-POSIX.1e semantics ACL. lib/libthr/thread/thr_single_np.c: /* Enter single-threaded (non-POSIX) scheduling mode: */ sbin/hastd/lzf.c: * bit pattern traps. Since the only platform that is both non-POSIX share/mk/sys.mk:# non-Posix rule set sys/cddl/contrib/opensolaris/uts/common/sys/synch.h: * non-posix symbols/constants, violating POSIX namespace restrictions. Hence, sys/contrib/libsodium/m4/ax_pthread.m4:# libraries is broken (non-POSIX). sys/contrib/openzfs/lib/libspl/include/umem.h: * with non-POSIX platforms that require a different free sys/contrib/openzfs/man/man1/cstyle.1:Check for use of non-POSIX types. sys/contrib/openzfs/scripts/cstyle.pl: -P check for use of non-POSIX types sys/contrib/openzfs/scripts/cstyle.pl: # try to detect old non-POSIX types. sys/contrib/openzfs/scripts/cstyle.pl: err("non-POSIX typedef $1 used: use $old2posix{$1} instead"); sys/contrib/zstd/programs/platform.h:* PLATFORM_POSIX_VERSION = 1 for Unix-like but non-POSIX sys/security/audit/audit_bsm.c: /* shm_rename is a non-Posix extension to the Posix shm implementation */ sys/sys/mac.h: * Extended non-POSIX.1e interfaces that offer additional services available
| bin/sh/sh.1 | ||
|---|---|---|
| 86 | Don't add this, instead fix the stale and contradictory statement on lines 80,82. That's how you keep the text down. More text requires more clever beans to process. | |
| bin/sh/sh.1 | ||
|---|---|---|
| 86 | Do you have any ideas on how to change the 80-82 sentence? To me it seems that if I would try to 'join' thoughts on 80-82 and 85-86, the result would be too overloaded. I don't mind removing 80-82 and using 85-86 instead, but that's only my opinion, maybe we shouldn't completely remove it. | |
Hmm...
The sh utility is the standard command interpreter for the system. The current version of sh is close to the IEEE Std 1003.1 (“POSIX.1”) specification for the shell. Non-POSIX extensions are marked below. This man page is not intended to be a tutorial nor a complete specification of the shell.
The sh utility is the standard command interpreter for the system. It's
behavior is standardized in the IEEE Std 1003.1 ("POSIX.1") specification
for the shell. Any extensions which are non-POSIX are marked below.
This manual is not intended to be a tutorial nor a complete specification
of the shell.This is hard because I really feel that information on standards belongs in the standardized section for standards, called STANDARDS... The first sentence is sacred, it's been there since the beginning and cannot be improved upon.
- Reword sentence about non-POSIX extensions (chose second variant suggested by ziaee).
- Change missed occurrences of 'Non-standard' -> 'Non-POSIX'.
I love this. Over to @jilles for the final say (and of course if anyone else has anything to say).
| bin/sh/sh.1 | ||
|---|---|---|
| 261–266 | The long name -o ignoreeof is specified by POSIX, but the short name -I is not. | |
| 275–277 | I'm not entirely sure what POSIX says about this but in practice -m in non-interactive mode is not entirely portable. | |
| 283–293 | Although the -L and -P options to cd and pwd are specified by POSIX, the -L option to set and sh is not. | |
| 311–318 | POSIX only specifies -s as option to sh, not -o stdin and not to set (the text already says this is useless, but bash reports an error instead and ksh93 sorts the positional parameters). | |
| 340–347 | The long name -o vi is specified by POSIX, but the short name -V is not. Also, the exact behaviour of the editor is not compliant. | |
| 361–372 | Although -o pipefail is specified by sufficiently recent POSIX, shells that don't support it (dash) are still quite common. Do we want to warn about features that are not portable in practice, too? | |
| 373–378 | The -o verify option is also non-POSIX. | |
| 381–385 | This description matches what POSIX says (-c reads from an operand, not an option-argument, so something like sh -c -- 'echo hi' writes hi), but not what we actually do. This is a bug which is hard to fix for compatibility reasons: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=220587 . I guess we can leave this as is in the manual page. | |
| 456–462 | Although dollar-single quote is specified by sufficiently recent POSIX, shells that don't support it (dash) are still quite common. Do we want to warn about features that are not portable in practice, too? | |
| 1081–1090 | Although case fallthrough is specified by sufficiently recent POSIX, shells that don't support it (dash) are still quite common. Do we want to warn about features that are not portable in practice, too? | |
| 1187–1191 | The local builtin itself is fairly portable but this part of it is not. Various shells have the variable start off unset instead. Applying unset to local variables also has variable effects. | |
| 1447–1448 | These sequences are also non-POSIX (the parameter expansion is specified though). | |
| 1589 | Perhaps add "non-POSIX" here too. This is not only an extension but also not portable in practice. | |
| 2149–2160 | This -e option is specified by sufficiently recent POSIX but is not portable yet in practice (dash, zsh). | |
| 2221–2227 | -e is non-POSIX, and so are operands containing backslashes. | |
| 2319–2322 | The behaviour of export by itself is not specified by POSIX. Often, this behaves like export -p instead. | |
| 2757–2759 | Like export by itself, the behaviour of readonly by itself is not specified by POSIX and not portable in practice. | |
| 2984 | POSIX only specifies -f, but in practice -c, -m, -s, -t, -u and -v are also fairly portable (although suitable values for memory limits also depend on architecture and system overhead). | |
Thank you for the review, @jilles!
| bin/sh/sh.1 | ||
|---|---|---|
| 283–293 | I can't see -L option to set, did you mean -P? | |
| 361–372 | Yeah, I think that would be great. I should use POSIX.1-2024 as the name of the edition it was added in, right? | |
| 1187–1191 | I'm not sure that we should also document if feature is fairly portable, but still is non-POSIX. On the other hand, warning about new POSIX features that may not be portable in all shells makes sense to me. The very fact that feature is not specified by POSIX doesn't let us be sure that we can safely use it. Not to the same degree at least. I don't insist of course, just my thoughts on it. | |
| 2221–2227 | And what about -n? As I can see, it is not portable too?: If the first operand consists of a '-' followed by one or more characters from the set {'e', 'E', 'n'}, or if any of the operands contain a <backslash> character, the results are implementation-defined.https://pubs.opengroup.org/onlinepubs/9799919799/utilities/echo.html | |
| 2757–2759 | In these cases, do you mean that POSIX doesn't specify export/readonly built-ins at all, or just their behaviour when they are invoked without arguments? I couldn't find information about neither of them on POSIX website. | |
| 2984 | As I can see, more options have been added in 2024: Austin Group Defect 1418 is applied, adding the -H, -S, -a, -c, -d, -n, -s, -t, and -v options https://pubs.opengroup.org/onlinepubs/9799919799/utilities/ulimit.html | |
| bin/sh/sh.1 | ||
|---|---|---|
| 283–293 | Right, I meant -P. | |
| 361–372 | Yes. | |
| 2221–2227 | Indeed. By the way, this also means that the -- argument is literal (not end of options marker), and our implementation implements that correctly. | |
| 2757–2759 | This is about the commands export and readonly without arguments. POSIX only specifies the behaviour with the -p option or with one or more operands (variable names with optional =values). | |
| 2984 | OK, I missed that. | |