Home |
Schily Bourne Shell
A modern enhanced and POSIX compliant Bourne Shell source maintained by Jörg Schilling

Welcome to the Schily Bourne Shell project

Schily Bourne Shell source download, get Schily-Tools (see latest schily-*.tar.* archives).

Read the Schily Bourne Shell man page.

Check the Schily-Tools development area at SourceForge.

Schily Bourne Shell is based on the OpenSolaris sources and thus based on SVR4 and SVID3.
The Schily Burne Shell is maintained by Jörg Schilling.
Source snapshots are published frequently with the Schily-Tools.

The Schily Bourne Shell

The Schily Bourne Shell was derived from the Bourne Shell sources from OpenSolaris.
See The Traditional Bourne Shell Family from Sven Mascheck and a talk from Stephen Bourne in June 2015 at BSDCan.
Some talks I held including shell differences and the shell in the POSIX standard.
The Schily Bourne Shell is actively maintained and enhanced on a regular base. It can be compiled into two variants.

The non-POSIX SVr4/OpenSolaris variant (osh):

The portable but not extended variant osh allows script portability testing.
Most scripts that run in the old Schily Bourne Shell will run with any Unix shell that is still in use since 1990.
As it is simple to write shell scripts that are both POSIX-conforming and usable with the Bourne shell,
this helps to write scripts that will work on a wide variety of target platforms.

The features of the original OpenSolaris Bourne Shell (osh) from the Schily tools are:

  • Processing of legacy scripts that some modern shell might not understand
  • Funtions with a private argument list and a return code. This is a standard feature from SVR4.
  • Job control similar to what csh introduced around 1979. This is a standard feature from SVR4.
  • Full i18n support in the shell allows it to be used in any locale. This is a standard feature from OpenSolaris.
  • The getopts(1) builtin supports long options as aliases to short options. The OpenSolaris getopt(3c) is included for portability.
  • Portability to most platforms as sbrk() was replaced by malloc() - this was not yet in OpenSolaris, it is a Schily-specific extension based on code donated by Geoff Collyer.
  • The POSIX compliant extended variant (bosh):

    This version has been verified to work as the system shell on Gentoo Linux and OpenSolaris (SchilliX).

    The enhanced Schily Bourne Shell (bosh) implements the following features that are missing
    in the OpenSolaris Bourne Shell listed above:

  • Integrated history editor based on a design and prototype from 1982 and the bsh(*) shell integration from 1984
  • Aliases that go beyond the features of aliases from other shells, e.g. persistent aliases and directory specific local aliases.
  • Hash commands (starting with #) to allow comfortable editing of persistent aliases in the history editor.
  • dosh builtin that allows to implement parametrized aliases.
  • pushd/popd/dirs builtin commands, taken from bsh(1) from 1985.
  • Fixed all known bugs from SVr4 and Solaris
  • Access to all 32 bits from the exit(2) code and exit reason on all modern UNIX variants with working waitid(2).
  • Rewritten parser, interpreter and jobcontrol makes the shell the parent of all simple commands from a pipe.
  • Rewritten parser, interpreter and jobcontrol results in echo bla | read var; echo $var to echo bla.
  • Rewritten parser, interpreter and jobcontrol reduces the number of forks and enhances performance.
  • Support for symbolic mode with the umask(1) builtin, needed for POSIX compliance.
  • Support for POSIX long shell options using set -o.
  • The getopts(1) builtin supports long options even without being just an alias to short options.
  • Built in find(1) command as a testbed for future runtime loadable builtin commands.
  • Built in pgrp, killpg, repeat, errstr and builtin command, taken from bsh(1) from 1985.
  • Enhanced ulimit command.
  • Support for read -r, needed for POSIX compliance.
  • set -a affects really all shell variables, even those created by read.
  • Support for all POSIX shell special macros (e.g. PWD, PS4, PPID).
  • First char from IFS becomes separator for "$*" expansion, needed for POSIX compliance.
  • Using vfork() instead of fork() where possible to enhance performance.
  • Pipes on other fd's than stdout (e.g. stderr) via set -o fdpipe and cmd 2| more
  • Support for set -o noclobber, set -o bgnice, noclobber is needed for POSIX compliance.
  • More test features (similar to ksh93)
  • Built in POSIX compliant printf command.
  • "--" support and general option support for POSIX utility syntax guidelines in builtin commands mentioned by POSIX
  • ! as a reserved word to logically NOT the exit code (required by POSIX)
  • "time" is supported as reserved word to trigger timing of complete pipelines. This is a ksh88 feature.
  • For POSIX compliance, an optional "(" is permitted before patterns from case constructs
  • The "command" builtin was added for POSIX compliance
  • Parameter substitution for these constructs was added for POSIX compliance:
  •    ${#parameter}               -> strlen(parameter)
       ${parameter%word}      -> Remove Smallest Suffix Pattern
       ${parameter%%word}   -> Remove Largest Suffix Pattern
       ${parameter#word}      -> Remove Smallest Prefix Pattern
       ${parameter##word}   -> Remove Largest Prefix Pattern
  • The "cd" builtin implements the special argument - for the previous directory
  • The "cd" builtin now implements the POSIX options -L and -P
  • The "pwd" builtin now implements the POSIX options -L and -P
  • The "pushd"/"popd"/"dirs" builtins now implement the options -L and -P
  • Command Substitution with $(cmd) was added for POSIX compliance
  • The listing of function definitions from the set(1) builtin now also lists "cmd 2| more" pipes.
  • The listing of function definitions from the set(1) builtin now lists case statements correctly.
  • The listing of function definitions from the set(1) builtin now lists the content from here documents.
  • It is now permitted to unset the shell variables PATH IFS PS1 PS2 MAILCHECK
  • The output from the "set" command with no arguments now uses "appropriate" quoting (if needed) to follow the POSIX "set" requirements
  • Permit functions with the same name as shell variables to follow POSIX requirements
  • Tilde expansion according to POSIX (at the beginning of a word and after : in variable assignments)
  • Empty commands in the form: ";" or ";echo" are now allowed.
  • The field splitting done by the "read" command is now POSIX compliant and no longer skips multiple field separators.
  • "set --" now clears all current arguments, needed for POSIX. The SVr4 way was to only set a new argument vector when there are arguments following to "set --".
  • "echo ${10}" now prints the 10th argument in the parameter list, needed for POSIX. Before, only $0..$9 have been supported.
  • "echo < nonexistent" (I/O redirection errors with builtins) no longer exit shell scripts, needed for POSIX.
  • Arithmetic Substitution with $((expression)) was added for POSIX compliance
  • Fixed a bug introduced in 1981 with SYSTEM III that caused continue large-number to break and not to continue the outer loop.
  • Fixed a bug introduced in 1981 with SYSTEM III that caused cat 0<<-EOF not to strip leading TABs.
  • Fixed a bug - present since 1977 - that caused an interactive shell that calls for i in 1 2 3 ; do echo $i; break 0; done stop working.
  • Added support for the select keyword from ksh88.
  • Added support for the local builtin command to implement local variables for functions.
  • Fixed a bug introduced by Sun in the 1990s that caused readonly unexported variables to be visible in scripts.
  •   The bug was introduced while trying to prevent unexported variables to be visible in scripts in general.
  • New option set -o posix to switch to real POSIX mode. This currently disables '^' as alternative pipe symbol.
  • Auto-enable set -o posix if shell path is /usr/xpg4/bin/sh or another configurable path.
  • The test builtin has been rewritten to be 100% POSIX compliant.
  • The lexer has been rewritten to identify ${a:+ } as a single word.
  • Redirection problems that are caused by a failing dup() call now print an error message and prevent to start the related command to e.g. stdout instead of the intended fd.
  • The POSIX rationale claims that IFS=o; violet should not execute "vi". This also affects constructs like IFS=o; echo "$@".
  •   This is in conflict with the normative text in the POSIX standard that describes the behavior of the historic Bourne Shell, but aligned with ksh.
      We now implement a similar hack as ksh88 and /usr/xpg4/bin/sh do.
      Future versions will behave similar to ksh93.
  • The default case exit code (when no case label matches) is now 0. The historical Bourne Shell did not initialize the exit code in this case.
  • The command set -u; echo "$@" no longer fails when no args are present.
  • Permit SIGSEGV with the "trap" builtin.
  • Do not list functions when calling "set" with no arguments in case full POSIX mode was enabled via set -o posix. - This is related to a bug in the POSIX standard.
  • type -F now lists all functions and may be used as an alternative to the "set" command when in full POSIX mode.
  • Support the POSIX shell variables HISTSIZE and HISTFILE.
  • Initialize PWD at program start.
  • Implement parameter expansion for PS1 and PS2.
  • New shell option set -o promptcmdsubst allows to enable command and arithmetic expansion for PS1 PS2 and PS4
  • Compound commands are no longer run in a subshell if stdin/stdout or stderr are redirected
  • Multiple non-space IFS chars now result in empty arguments
  • When on POSIX mode, variables imported from the environment are automatically exported, there no longer is a split namespace that exports the original value but permits to change the internal value
  • The command ( trap "echo exiting" EXIT; /usr/bin/true ) now fires the EXIT trap. This is a bug introduced in 1977 already.
  • In the command sh -c "echo foo" more optons are allowed to appear between -c and the command string
  • sh -c "set -e; echo foo `false`" no longer exits before printing foo
  • failing command substitution commands no longer set the default exit code for exit/return without parameter
  • /non/existent 2>/dev/null did redirect the error message but non-existent 2>/dev/null did not redirect. This is a bug introduced in 1977 already.
  • The shell /tmp/file management now copies the /tmp/file in case that link() fails. This helps to make the shell run on Haiku that does not support link().
  • The quoting state is reset before here documents are expanded and restored thereafter. This avoids annoying backslashes in here documents that appear inside double quotes.
  • ...
  • Red bullets: Changes made to match the current POSIX standard.

    Read a whitepaper that compares the SVr4 shell with the current POSIX shell.
    No features are currently missing for POSIX compliance, but this will need to to be implemented in the future:

  • Support for $'...' quoting - not needed with the current POSIX standard, this is for the next POSIX version (SUSv8)
  • Green bullets: Not needed for the current POSIX standard, because a bug the current standard needs to be fixed first - or a feature not yet in the current standard.

    The performance enhancements in the Schily Bourne Shell result in almost 10% faster execution
    than with the original OpenSolaris Bourne shell while running a typical autoconf script.
    The Schily Bourne Shell is even faster than dash in this situation, but it supports
    multi byte characters that are not supported by dash.

    *) bsh is the "H. Berthold AG" shell for BERTOS - a virtual memory aware UNOS derivative, developed between 1982 and 1984.

    Copyright © 2018 J. Schilling Last Change 2017/07/20.