This is a fork of the public domain es(1)
shell, the original, from 1997 can be fetched from one of the following locations:
- ftp://ftp.sys.toronto.edu/pub/es/es-0.9-beta1.tar.gz
- ftp://ftp.sys.utoronto.ca/pub/es/es-0.9-beta1.tar.gz
Can be pronounced as an initialism same as shell like csh
, ksh
, zsh
, etc. ("en ecks ee ess") or
as "nexus".
See the LICENSE file for full details, but this code is made available under the 0BSD license. For all intents and purposes, this code remains in the public domain, in the same spirit as the initial (known) authors: Byron Rakitzis, Paul Haahr, and Soren Dayton.
So far, this version of es(1)
has been extended with the following primitive operations:
- Integer addition/subtraction (
sum
&sub
) - Integer multiplication (
mul
) - Integer division (
div
) - Modulus operation (
mod
) - Bitwise AND (
band
) - Bitwise NOT (
bnot
) (NOTE: Unary operation) - Bitwise XOR (
bxor
) - Bitwise OR (
bor
)
The additional primitives do not print the results to stdout
, instead they're returned much like
in a programming language. Their use is therefore quite different from using POSIX sh
or GNU bash
,
and shares at least superficial similarity with the LISP family of languages.
Note: Semicolon (';
') is the default prompt.
# Addition
; echo <={sum 1 2 3}
6
# Subtraction
; echo <={sum -1 -2 -3}
-6
# Alternative subtraction
; echo <={sub 10 20 30 -5}
-35
# Multiplication
; echo <={mul 2 4 6}
48
# Division
; echo <={div 20 2 2}
5
# Modulus
; echo <={mod 5 3}
2
# Bitwise AND
; echo <={band 1 3}
1
# Bitwise OR
; echo <={band 1 4}
5
# Bitwise XOR
; echo <={bxor 7 3}
4
# Bitwise NOT
; echo <={bnot 0}
-1
All of these operations work on signed 64-bit integers, there's not currently any bounds or sanity checking on the inputs, so use with care if you need such large values in your interactive shell scripts/sessions.
Under the examples/
directory are some files that should be of particular interest in both showcasing
the capabilities of this shell as well as syntax highlighting for {n,}vi{,m}.
-
examples/esrc.haahr
- Paul Haahr's annotated startup configuration, included primarily for historical reasons, as many of the functions used won't apply to the overwhelming majority of potential users.
-
examples/esrc.newnix
- My personal, evolving startup configuration. I'll try to keep it well annotated to make it even easier to follow along
-
examples/nxes.vim
- Vim syntax file, should be installed to
~/.config/vim/syntax/nxes.vim
or a similar location, useset ft=nxes
to activate
- Vim syntax file, should be installed to
The installation process should be relatively straightforward, though I've had some issues with undefined types show up when trying to compile on Ubuntu 20.04 LTS. On Void Linux with musl libc, clang 10, bmake, and byacc however, no such issue has appeared. Any C compiler should work, but I have not had time to validate this yet.
My process was as follows:
$ CC=clang LD=ld.lld ./configure --with-readline
$ make YACC=byacc ADDCFLAGS="-D_DEFAULT_SOURCE -D_POSIX_SOURCE=200809L -std=c99"
# Of course, run 'sudo make install' to install the compiled binary and manual page to whatever PREFIX is set to
$ ./es
; echo <={$&version}
nxes version 0.0-alpha0 20200804
I've been able to verify successful builds including expected behaviour when linking against readline on the following platforms:
- OpenBSD 6.7
- Void Linux (musl libc)
- HardenedBSD 12.1
Consult the manual page (roff
formatted) "es.1" for complete details.
Please read through README.orig to see the original text, especially as this is under construction.
Some goals for the future of this fork (in no particular order):
- Modernize codebase (Drop obsolete hacks, attempt to make future maintenance easier)
- Add primitives to facilitate use as a glue language or midway point between POSIX
sh
and "real" languages like Racket/C/Python, etc. - Work on making
nxes
tail recursive, this is mentioned in the original TODO (#2) - Add some basic history manipulation commands such as
!!
and!-2$
in GNUbash
to aid in productivity - Allow subshells to inherit closures (#1 in original TODO)
- Potentially expose
%parse
in such a way as to create a simple macro system - Simplify and streamline build process
- Look at moving away from Yacc/Bison for writing the lexer/parser
- Allow for nested lists, in turn allowing for trees and other derived data structures
- Look into creating a
printf(1)
builtin for more complex printing needs than just$&echo
- Consider changing variable/function binding syntax using more LISP-like forms, this would free up
=
from being a special character, which should make flags requiring '=' (e.g.clang -std=c99
) more ergonomic than with the current parsing grammar. (having to do'='
or similar) - Flesh out job control mechanism, support exists for creating new process groups and background execution, but no means to switch from background to foreground currently exists
Some non-goals:
- Become a strict, functional programming language
- Become a lazy, functional programming language
- Rewrite in Rust or other language (maybe some day, but this is not a goal)
- Become feature compatible with GNU
bash
(or really any other shell, some features are nice, but let's keep things small)