| ERISHELL(1) | General Commands Manual | ERISHELL(1) |
NAME
erishell - ERIS language evaluator
DESCRIPTION
erishell is a utility instructed by a
language specific to ERIS storage interactions.
The language aligns to the minimalist concatenative model of Joy. The most fundamental concepts within the language are stacks and programs. A stack is a collection of stacks and programs. A program takes a stack as input and produces a stack as output. The behavior of an undefined program is to append itself to the stack it is called with. The terms stack and set are used interchangeably where set operations are applied.
Programs may contain spaces and the parser will not split tokens containing whitespace if they are enclosed by the single-quote character ‘'’. The single-quote may be escaped with another single-quote: “'x''y'” parses to “x'y”.
The parser does not parse stacks and does not recognize [ or ].
For compatibility with the execlineb parser the
empty-string program “” creates a stack out of immediately
preceding programs that are prefixed with the ASCII space character (0x20)
with leading space character removed. By this rule the tokens
'0' ' 1 ' 2' '' would parse to
0 [1 2].
Documentation of the builtin programs follows. The syntax of program descriptions are INPUT | OUTPUT where the program described is at the the top (right side) of INPUT and the effect of the program is to replace INPUT with OUTPUT.
9p-listen-
S P O 9p-listen- | S
N
Pop socket path or TCP address P and options O then serve 9P from store S and push N which is closeable. The options set is for forwards compatibility and no options are presently recognized.
and-
A B and- | C
Pop sets A and B then push the intersection set C. Set intersection is provided for completeness and seldom used. Use or- for the more common union of sets.
badger-
P A badger- |
S
Pop path P and set of allowed operations A then push a store backed by a BadgerDB database at that path. Unix only. BadgerDB
bind-
X S bind- |
Pop programs S and X then replace symbol S in the current scope with a program that pushes X.
bindings- | ...
Push the name of each binding onto the stack. This is provided for generating shell completions.
bolt-
P A bolt- | S
Pop path P and set of allowed operations A then push a store backed by the Bolt database at that path. BoltdDB
buffer-
buffer- | B
Push a memory buffer that is readable and writable.
cache-
B F cache- | B F
C
Push store C that gets blocks first from F and any missed blocks are then gotten from B and put to F.
cbor-decode-
S R cbor-decode- |
S
Pop read stream R and deserialise CBOR encoded blocks from it into store S. See CBOR Serialization of ERIS Encoded Content.
cbor-encode-
W cbor-encode- | W
S
Push store S that receives blocks and serialises them as CBOR to the stream W. See CBOR Serialization of ERIS Encoded Content.
cbor-parse-caps-
R cbor-parse-caps- |
C Pop CBOR read stream R then
push the set of parsed ERIS read capabilities.
close-
X close- |
Pop X and close according to its local semantics.
coap-
S O coap- | S
E
Pop set of operations O then push a local CoAP endpoint that services remote CoAP requests using the store S as allowed by O. Endpoint E is usable as a store and will service local requests using remote peers. The initial store is available from /. If operations O allows neither GET nor PUT then S is not used and no store is bound to /.
There are no means to control what operations can be made to and from CoAP peers other than limiting what operations peers can make on the store below and by what requests are made to CoAP as a store on the stack above. Create multiple CoAP endpoints to implement multiple policies. See ERIS over CoAP.
coap-bind-
S E P O | S E
Bind ERIS store S to CoAP endpoint E at path P with supported operations O. If O allows neither GET nor PUT then S is not used and any existing binding at P is removed.
coap-discover-link-
E coap-discover-link- |
E
Configure CoAP endpoint E to discover peers using the CoAP link-scope multicast address. This does not listen on the multicast address and can therefore be used while the multicast address is already in use. Use this for client endpoints that do not provide storage instead of coap-listen-link-.
coap-listen-link-
E F coap-listen-link- |
E
Pop network interface pattern F then configure CoAP endpoint E to listen for and discover peers at the multicast link address on interfaces matching E. Use this for CoAP endpoints that provide storage service instead of coap-discover-link-.
coap-listen-
E U coap-listen- |
E
Pop URL U then configure the CoAP endpoint E to listen at the specified URL. The URL must contain either a port number or a schema.
coap-peer-
E U coap-peer- |
E
Pop URL U then add a to CoAP endpoint E a peer at the URL. The URL must contain either a port number or a schema.
compress-
compress- |
[compress]
Push the compress option set used by
mkfs-.
convergent-
convergent- |
[convergent]
copy-
W R copy- | W
Pop read stream R and copy the entire stream to write stream W.
decode-
S C decode - | S
R
Pop read capability C and push read stream R that decodes from store S.
decode-caps-
decode-caps |
[decode-caps]
Push the set of the decode-caps program as
a stack. Equivalent to ‘decode-caps
singleton-’.
dirstore-
P A dirstore- |
S
Pop path P and set of allowed operations A then push store S that puts and gets from P.
discard-
discard- | S
Push an ERIS store that discard any block put to it and fails to get anything.
drain-
R W drain- |
Pop write stream W and R then copy the entire Read stream to the write stream.
dumpfs-
S C P dumpfs- |
S
Pop the file-system path P and the read capability C then dump the ERIS-FS tree for which the capability corresponds to that path from the store S.
dumpfs-tar-
S C W dumpfs-tar- |
S
Pop the write stream W and the read capability C then dump the ERIS-FS tree for which the capability corresponds from the store S to that stream.
dup-
X dup- | X X
Duplicate the top of the stack.
encode-
S R O encode- | S
C
Pop option set O, read stream
R, encode it to store S, and
push read capability C. If the option set contains
convergent then encoding will be non-unique. If the
option set contains erislink then the read
capability is serialised as an ERIS link held in a temporary buffer.
erislink-
erislink- |
[erislink]
Push the erislink option set used by encode- and mkfs-. See ERIS link files.
erisfs-upgrade-
S A O erisfs-upgrade- | S
B
Pop options O and ERIS-FS capability A. Decode A from store S then encode to S an equivalent ERIS-FS according to the latest standard and push the corresponding capability B. The recognized option set is the same as the mkfs- program.
error-
X error- |
Pop X and raise it as an error.
fd-
N fd- | X
Pop natural number and push a stream that reads or writes to that file descriptor.
fuse-
S P O fuse- | S
F
Pop options O and mountpoint path P then serve FUSE there from store S and push F which is closeable. The options set is for forwards compatibility and no options are presently recognized. Linux only.
get-
get- | [get]
Push the set of the get program as a
stack. Can be combined with put as
‘get- put- or-’. Equivalent to
‘get singleton-’.
halt-
halt- |
Halt the evaluation of incoming programs and revert to a previous program stream.
http-client-
U http-client- |
S
Pop URL U then push a store that requests blocks over HTTP from that URL. Prefer CoAP. The URL must contain either a port number or a schema.
http-
S O http- | S
H
Pop option set O then push an HTTP server backed by store S. If the options set contains ‘decode-caps’ then the HTTP server will decode ERIS capabilities on request. Set this option using decode-caps-. See ERIS over HTTP.
http-bind-fs-
H C P http-bind-fs- |
H
Pop request pattern P and ERIS-FS read capability C then bind a handler that services request for P from file-system C at HTTP server H
http-listen-
H U http-listen- |
H
Pop URL U then bind HTTP server H to it. The URL must contain either a port number or a schema.
id-
id- |
Identity function.
log-
X log- |
Pop and log X.
memory-
B memory- | S
Pop natural number of bits B and push a store that holds blocks in memory where blocks are indexed by the first B bits of the block reference. The approximate effective capacity of the store is 2^(B-1).
multiplexer-
multiplexer- |
M
Push an empty store multiplexer. Add stores with multiplex-.
multiplex-
M S multiplex- |
M
Pop store S then add it to multiplexer M.
mkfs-
S P O mkfs- | S
C
Pop option set O, file-system paths P, encode it to store S, and push read capability C. The following symbols within the options set are recognized:
compress- All files will be
Lzipcompressed before encoding. convergent- Encoding will be non-unique.
erislink- The read capability is serialised as an ERIS link held in a temporary buffer. See ERIS-FS: A format for encoding file systems.
mkfs-tar-
S R O mkfs-tar- | S
C
Pop option set O, tar stream R, encode it to store S, and push read capability C. The mkfs-tar- program recognizes the same options as mkfs-.
null-
null- | []
Push the null set.
or-
A B or- | C
Pop sets A and B then push the union set C.
pogreb-
P A pogreb- |
S
Pop path P and set of allowed operations A then push a store backed by the pogreb database at that path. Available on Unix and Plan 9. Pogreb.
pop-
X pop- |
Pop the stop of the stack. Programs that represent a statefull background task like stores and servers continue to run after being popped. The close- program is run against them automatically before termination.
put-
put- | [put]
Push the set of the put program as a
stack. Can be combined with get as
‘put- get- or-’. Equivalent to
‘put singleton-’.
repl-
repl- | ...
Suspend execution of the main stack then read and evaluate programs from stdin while printing results to stdout. The halt- program resumes the main stack.
rolldown-
X Y Z rolldown- | Y Z
X
rollup-
X Y Z rollup- | Z X
Y
rotate-
X Y Z rotate- | Z Y
X
singleton-
X singleton- |
[X]
Pop X and push singleton set of X. Combine this with the or- program to build sets of multiple elements.
srv-
S N srv- | ...
Pop the name N and post a 9P service channel at /srv/N backed by store S and a command channel at /srv/N.cmd. Execution of the main stack is suspended and programs are read from the command channel until the halt- program is evaluated. The main stack is then resumed with result of the command channel. ‘halt’ is aliased to halt- for compatibility reasons.
ERIS-FS can be attached by read capability using the command
mount -C /srv/eris /n/eris
urn:eris:B4A...NHIcon -C /srv/eris.cmdPlan 9 only.
store-copy-
S X store-copy- |
S
Pop store X and copy all blocks to store S.
store-trace-
S L store-trace- | S
T
Pop label L and push a store that labels and logs all operations at store S.
swap-
Y X swap- | X
Y
wait-
wait- |
Wait for a background task to complete. Use this to run
erishell as a server.
EXAMPLES
9P
Listen for 9P clients on a Unix socket:
erishell null- coap- '.*' coap-listen-link- 8 memory- cache- /run/eris.9p null- 9p-listen- wait-
Mount an ERIS-FS using the Linux v9fs client:
mount -t 9p /run/eris.9p /mnt -o ro,trans=unix,version=9p2000,cache=loose,aname=urn:eris:B4AFMOZDVKXZH6T24HSA4HRQCUZKPYXIETPAIHJGRFPADE4T2C3DE4DTERDUUIMK4PVDOU2ZLDB664W4V3J7LGIFCYI6D4L66ZLWBDZ764
Encoding
Encode an ERIS URN:
#!/bin/sh echo -n 'Hail ERIS!' | erishell discard- 0 fd- null- encode- swap- close-
Encode an ERIS link file:
#!/usr/bin/env -S execlineb -P redirfd -r 3 test.dat redirfd -w 4 test.dat.eris erishell discard- 3 fd- convergent- erislink- or- encode- 4 fd- swap- copy- close- close-
Open and close a pogreb store so that basic consistency checks are run on the database:
/var/cache/eris.pogreb put- pogreb-
close-Open a database, encode from standard input, log the capability, then listen for CoAP peers.
/tmp/eris.pogreb get- put- or- 0 fd-
null- encode- log- get- coap- .* coap-listen-link- wait-CBOR
Encode content on stdin to CBOR serialisation on stdout:
1 fd- cbor-encode- 0 fd- convergent-
encode- swap- close- swap- close-Decode CBOR serialisation from stdin to a pogreb database:
/var/cache/eris put- pogreb- 0 fd-
cbor-decode-Encode an ERIS-FS and then parse the read capabilities within:
8 memory- ./ convergent- mkfs-
decode- cbor-parse-caps-CoAP
Serve an open link-scope store on wired-ethernet devices:
16 memory- get- put- or- coap- eth.*
coap-listen-link-Serve 9P backed by CoAP and a local cache:
erishell \ 'create a temporary pogreb database' log- \ /tmp/pogreb put- get- or- pogreb- \ 'push a CoAP endpoint that can get blocks from the database' log- \ get- coap- 'connect to a peer to GET from' log- \ eris.example.org:5683 coap-peer- \ 'put the local DB as a cache in front of CoAP' log \ swap- cache- \ 'announce /srv/eris using the composed stores' log- \ eris srv-
ERIS-FS
Encode an ERIS-FS tree from a git tree:
git archive --format=tar HEAD | erishell \ null- coap- [::1]:5683 coap-peer- \ 0 fd- compress- convergent- or- mkfs-tar-
File Descriptors
Fish function to stream into VLC:
function eris-vlc --wraps=vlc
if test -z $TMPDIR
set -f TMPDIR /tmp
end
set -f port (random)
erishell \
$TMPDIR/eris.db get- put- or- pogreb- \
get- coap- \
coap-discover-link- \
eris.example.org coap-peer- \
swap- cache- \
decode-caps- http- \
"[::1]:$port" http-listen- \
wait- &
for urn in $argv
set -f -a urls "http://127.0.0.1:$port/uri-res/N2R?$urn"
end
vlc $urls
kill $last_pid
end
FUSE
Transparent ERIS decoding at /n/eris:
/var/cache/eris get- pogreb- /n/eris
null- fuse- wait-HTTP
Serve a static photo gallery:
fgallery \ ~/Pictures /tmp/static-gallery erishell \ /var/db/gallery.eris.pogreb get- put- or- pogreb- \ /tmp/static-gallery/ convergent- mkfs- swap- close- \ >gallery.urn erishell \ /var/db/gallery.eris.pogreb get- pogreb- \ null- http- \ $(cat gallery.urn) \ /my/gallery/ http-bind-fs- \ 'listen for clients' log- \ 0.0.0.0:80 http-listen- \ [::]:80 http-listen- \ wait-
REPL
Create an HTP server backed by CoAP and local storage then interactively add storage and a CoAP peer.
$ erishell \ 'create a multiplexer' log- \ multiplexer- \ 'create a CoAP endpoint that serves the multiplexer' log- \ get- coap- \ 'swap the multiplexer for CoAP' log-\ swap- \ 'use the multiplexer as a cache in front of CoAP' log- \ cache- \ 'create an HTTP server that serves from the cache' log- \ null- http- \ 'pop the cache and bring CoAP and the multiplexer up' log- \ swap- pop- rollup- \ 'enter REPL' log- \ repl- \ erishell# 'add database store to multiplexer' log- erishell# /tmp/store get- put- or- pogreb- multiplex- erishell# swap- erishell# 'add CoAP peer' log- erishell# coap://eris.example.org coap-peer-
stores
Copy a Badger store to a Pogreb store.
./eris.pogreb get- put- or- pogreb-
./eris.badger get- badger- store-copy-NNCP
Convergently encode from stdin to NNCP:
erishell \ 1 fd- cbor-encode- \ 0 fd- convergent- encode- \ swap- close- log- \ | nncp-exec -nocompress -nice BULK bob eris-put-cbor
Note that close- is used to remove the CBOR store from the stack and log- to write the ERIS URN to stderr, clearing the stack. Otherwise the contents of the stack would be written into the CBOR stream.
NNCP configuration for receiving ERIS blocks and importing to a CoAP endpoint on the localhost:
# /etc/nncp.hjson
{
neigh: {
alice: {
exec: {
eris-put-cbor: [
/bin/erishell
null- coap-
localhost coap-peer-
"0" fd- cbor-decode-
close-
]
}
}
}
}
Third-party leaks
Encode content and split the read capability using the ssss(1) Shamir's Secret Sharing Scheme utility from http://point-at-infinity.org/ssss/ and redirfd(1) from https://www.skarnet.org/software/execline/redirfd.html.
# Uniquely encode ./insurance directory to a dump of CBOR blocks: $ redirfd -w 3 insurance.eris.cbor \ erishell 3 fd- cbor-encode- \ ./insurance compress- mkfs- \ rollup- close- close- urn:eris:B4A3Z... # Split the read capability: $ echo urn:eris:B4A3Z... \ | ssss-split -t 3 -n 4 Generating shares using a (3,4) scheme with dynamic security level. Enter the secret, at most 128 ASCII characters: Using a 920 bit security level. 1-560189... 2-1a990e... 3-508bdf... 4-5bb823... # Distribute the secrets to trusted parties and # publish the insurance.eris.cbor dump.
Combine keys and recover content
# Combine secrets to recover read capability. $ ssss-combine -t 3 Enter 3 shares separated by newlines: Share [1/3]: 2-1a990e... Share [2/3]: 3-508bdf... Share [3/3]: 4-5bb823... Resulting secret: urn:eris:B4A3Z... # Deserialise CBOR dump into a temporary database then decode files: $ erishell \ /tmp/blocks.db put- get- or- pogreb- \ 0 fd- cbor-decode- \ urn:eris:B4A3Z... ./disclosure dumpfs- \ close- \ < insurance.eris.cbor $ cd ./disclosure
SEE ALSO
STANDARDS
ERIS
ERIS-CBOR
ERIS-CoAP
ERIS-FS
ERIS-HTTP
ERIS-link
HISTORY
erishell was preceded by the eris-go(1) utility. eris-go was awkward to use. A refactor was made using an internal configuration model which could be declared as JSON and the command-line interface redesigned according to the Command Line Interface Guidelines, https://clig.dev/.
The CLIG brought eris-go close to the heavenly aspirations of UX,
but those whose thirst for arcane power condemned the interface as stupid
and limiting. In a fit of inarticulate rage, they cast the implementation
into the abyss of primordial semantic forms and it was reborn as
erishell.
AUTHORS
Emery “hell is other peoples' tools” Hemingway
BUGS
Early versions of erishell encode an
invalid interpretation of the ERIS-FS
version 1 standard where the top-level dictionary of the ERIS-FS index is
keyed by a Unix-style filename as a CBOR text string. The correct encoding
is an index keyed by arrays of CBOR text strings where Unix-style paths are
decomposed into directory and file components. This version only encodes
using ERIS-FS version 2 but makes an effort to load incorrect encodings of
version 1. ERIS-FS version 0 is unsupported in either case.
| 2026-08-29 | Synit-SLAM |