Help us shape the future of Go! Take the 2026 Go Developer Survey

sh

module
v0.0.36 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2026 License: Apache-2.0

README

sh

CI Release CodeQL OpenSSF Scorecard Go version Go Reference

A shell parser and interpreter in Go.

Status: early — these are 0.x tags and they mean it. The core parser and interpreter are in place, and all five dialect binaries grade against a panel of the real shells they model. Measured on macOS against the golden record make oracle writes, 2026-10-04, 4488 cases each:

our binary graded against exact behavioral
bash bash 5.3.20 99.8% 99.8%
zsh zsh 5.9.2 99.8% 99.8%
dash dash 99.9% 99.96%
ksh ksh93 AJM 93u+ 99.1% 99.5%
ash BusyBox 1.37 ash 99.5% 99.6%

ash is graded inside the pinned BusyBox container, with ours cross-compiled and run beside it, so both sides share one platform (#5709).

Every case still short of exact is listed per dialect in internal/oracle/testdata/conformance/, and CI's conformance ratchet fails a change that adds to a list or leaves a fixed case on one. Each listed case has a written reason in docs/spec/by-design.md — the reference shell crashes or hangs, the panel's own builds disagree, a C-library quirk rather than the shell, or a deliberate choice — and a test fails a listed case without one, so the rest of the distance is decided, not unfinished.

Exact is byte-identical stdout, stderr and exit status. Behavioral lets a diagnostic be worded differently so long as the status and the standard output agree; a case that prints something else on standard output is a behavioral difference however it exits. Until 2026-10-03 the column counted the status alone and read 99–100% (#5708).

Two bash builds are in play and they do not always agree. This table is the laptop's bash 5.3.20; the bash suite in CI is graded against debian:sid-slim's 5.3.15, the same release and a different patch level. Where the two disagree, the common denominator of the panel decides and the difference is written down — ~ after a HOME assignment is the worked example, in docs/spec/grammar/expansion.md. Behavior lands spec-first, per CLEANROOM.md.

What makes this different

The core language is the common denominator of real shells — not strict POSIX, and not bash. Dialects (bash, zsh, ksh, dash, ash, plus core and posix) are presets over a semantics vector, not layers, translations or forks.

That distinction is not stylistic. Measuring twenty-eight behavioral axes across dash, bash, ksh93 and zsh produces eight different groupings of those shells — dash sides with zsh on echo, bash sides with zsh on shift, ksh93 sides with zsh on pipelines. No "sh → bash → zsh" ladder explains the data. Dialect is a point in a multi-dimensional space, so the model is a vector of independent switches. See docs/spec/semantics.md.

Execution is gateable and observable from the inside. Sandbox policy, agent permission prompts, AI context and audit trails are interpreter-internal seams rather than wrappers, because eval and source re-parse inside the interpreter and a wrapper never reaches them. See docs/design.md.

Independence

This is an independent implementation. It is not a fork or a port of any existing project, and no file here derives from one. Behavior is learned from POSIX, from vendor manuals, and from running real shell binaries as oracles; it is written down in docs/spec/; code is written from the spec. CLEANROOM.md is the binding rule set.

Installing

From the tap:

brew install blairham/tap/sh

Or from source:

make install                           # /usr/local/libexec/sh — needs sudo to write
make install PREFIX="$HOME/.local"     # no sudo

Six shells: sh, and the dialect binaries bash, zsh, ksh, dash and ash. They land in libexec and not in a bin directory, because they are named after the shells they model — a directory ahead of /bin on PATH would answer for every program on the machine that resolves a shell by name. make install refuses a SHELLDIR that is on PATH unless it is told to go ahead, and the formula keeps them out of Homebrew's bin for the same reason.

So you run one by its full path, and docs/install.md has the whole of it — including what /etc/shells and chsh need to make one of them a login shell, and how to try one first as a terminal profile's command, which is a checkbox to revert rather than a rescue.

The formatter shfmt is the exception. The tap does put it on your PATH, because that rule is about names a machine resolves implicitly — a shebang, a system(), a chsh — and nothing resolves a formatter that way; an editor or a pre-commit hook calls it by name or not at all. Homebrew's own shfmt (mvdan.cc/sh) wants that name too, so the formula declares the conflict and you pick one. make install does not install shfmt at all yet.

There is a container image per shell as well, FROM scratch — the static binary, two files and two empty directories:

docker run --rm -it ghcr.io/blairham/sh/scratch/bash:latest

The reason they exist is the other direction: a distroless image has no shell on purpose, and one COPY --from gives it one without giving it a libc, a package manager or a userland. docs/install.md has what is in them and what a scratch image does not have.

Those images carry a whole shell, which can run whatever the image holds. For a shell an operator can only look with — no exec ever, reads bounded to /proc and /sys/fs/cgroup, every action recorded — link the gated package into your own image's /bin/sh; gated/README.md has the five-line main and the Dockerfile lines.

A session reads everything a real shell of the same name reads, in the same order: ~/.bashrc, ~/.zshrc, the profile files, and the machine's own file in front of each. docs/install.md has the measured grid.

What is not there yet

The tags are 0.x because this list is real, not because the list is short.

  • Diagnostic wording is a long tail, not the headline gap. This list used to open by saying wording was most of the distance above, and two measurements disagree. One is the ksh re-count beside the table. The other is a bounded sample, first run 2026-09-16: twenty error situations a person actually hits — a missing command, cd onto a file, set -u on an unset name, a redirect that cannot open, division by zero, an unknown option to six different builtins, running a directory, exit foo — each run once through the real shell and through ours under a matching argv[0], compared on stderr and exit status together. Re-measured 2026-09-27: byte-identical 20/20 on every one of the five, 100 of 100, ash included — its reference is a container, and the 16/20 it read on 2026-09-16 is gone along with the ksh and zsh misses of that day. Twenty common situations is a sample and not a census, and the corpus behind the percentages above is two hundred times larger and much stranger. The probe is internal/cmd/diagsample, a few seconds a column, so this bullet can be re-checked rather than inherited — which is how it came to be wrong: its only previous instrument was an hour-long conformance run, so nobody ever ran it to find out.
  • The sandbox contains the shell, not the process tree. A policy decides what the shell opens, runs and signals; a command it was allowed to start makes its own accesses and nothing here sees them. docs/design/sandboxing.md has the scope limit in full.
  • POSIX only. No Windows target — every route into this program is a process group, a controlling terminal, a signal or a syscall.Exec, and a binary that cannot start is worse than no binary.

Using it as a library

The core is a library, and it does not know which shells exist: syntax and interp define the questions, and each shell answers them in its own package under dialect/.

sem, dial, diag := bash.Semantics(), bash.Dialect(), bash.Diagnostics()
r := &interp.Runner{Semantics: &sem, Dialect: &dial, Diagnostics: &diag}
bash.Apply(r)                      // what this shell adds or removes

r.Register("cd", cd)               // only what shell cannot express

prelude, _ := syntax.Parse(`basename() { printf '%s\n' "${1##*/}"; }`, dial)
r.Run(ctx, prelude)                // everything else

Adding a shell adds a directory. Nothing under syntax/ or interp/ names one.

Functions shadow builtins and external commands alike, so most of a dialect needs no Go at all.

Layout

CLEANROOM.md              the rules that keep this independent
docs/install.md           installing, and running it as a login shell
docs/design.md            architecture
docs/lessons-carried-forward.md
                          starting constraints, learned the hard way
docs/spec/                behavioral specs — the wall
  oracle.md               how behavior is learned from real binaries
  shell-matrix.md         measured: which constructs exist where
  semantics.md            measured: where shells conflict
  core.md                 the core language boundary
  style.md                measured: how source is laid back out
  grammar/                per-construct specs
cmd/shfmt                 the formatter — every dialect the parser reads
gated/                    a /bin/sh for distroless images that cannot exec

License

Apache-2.0. See LICENSE and NOTICE. Report vulnerabilities privately — see SECURITY.md. Participation is under the CODE_OF_CONDUCT.md.

Contributions require a signed CLA — see CONTRIBUTING.md and CLA.md. The CLA exists so the project retains the option to offer different terms later; you keep your copyright.

Directories

Path Synopsis
cmd
ash command
Command ash is a BusyBox ash dialect built on the core.
Command ash is a BusyBox ash dialect built on the core.
bash command
Command bash is a bash dialect built on the core.
Command bash is a bash dialect built on the core.
dash command
Command dash is a dash dialect built on the core.
Command dash is a dash dialect built on the core.
ksh command
Command ksh is a ksh93 dialect built on the core.
Command ksh is a ksh93 dialect built on the core.
sh command
Command sh drives the substrate.
Command sh drives the substrate.
shfmt command
Command shfmt lays out shell scripts, in every dialect the substrate parses: the core, posix, dash, bash, ksh93 and zsh.
Command shfmt lays out shell scripts, in every dialect the substrate parses: the core, posix, dash, bash, ksh93 and zsh.
zsh command
Command zsh is a zsh dialect built on the core.
Command zsh is a zsh dialect built on the core.
Package dialect holds one package per shell the substrate imitates.
Package dialect holds one package per shell the substrate imitates.
ash
Package ash answers the substrate's questions the way BusyBox ash does.
Package ash answers the substrate's questions the way BusyBox ash does.
bash
Package bash answers the substrate's questions the way bash 5 does.
Package bash answers the substrate's questions the way bash 5 does.
dash
Package dash answers the substrate's questions the way dash does.
Package dash answers the substrate's questions the way dash does.
ksh
Package ksh answers the substrate's questions the way ksh93 does.
Package ksh answers the substrate's questions the way ksh93 does.
zsh
Package zsh answers the substrate's questions the way zsh does.
Package zsh answers the substrate's questions the way zsh does.
Package driver is the front end a dialect needs in order to be a program.
Package driver is the front end a dialect needs in order to be a program.
Package gated is a shell that cannot run anything, for images that have no shell at all.
Package gated is a shell that cannot run anything, for images that have no shell at all.
internal
acp
Package acp speaks the Agent Client Protocol, in both directions.
Package acp speaks the Agent Client Protocol, in both directions.
acpboot
Package acpboot supplies driver.Shell.ServeACP.
Package acpboot supplies driver.Shell.ServeACP.
acpcheck
Package acpcheck is a real ACP client, used to grade a real ACP agent.
Package acpcheck is a real ACP client, used to grade a real ACP agent.
asttree
Package asttree writes a parsed program out as Go source: one composite literal that the compiler lays down in the binary's data, so the tree costs nothing to build when the program starts.
Package asttree writes a parsed program out as Go source: one composite literal that the compiler lays down in the binary's data, so the tree costs nothing to build when the program starts.
axismutate
Package axismutate moves one field of a settings struct to a value it does not hold, so that something else can ask whether anything noticed.
Package axismutate moves one field of a settings struct to a value it does not hold, so that something else can ask whether anything noticed.
axissweep
Package axissweep asks, of every axis in interp.Semantics, whether anything fails when it is moved.
Package axissweep asks, of every axis in interp.Semantics, whether anything fails when it is moved.
blocks
Package blocks stores a command and what came of it as one record.
Package blocks stores a command and what came of it as one record.
boundary
Package boundary asks a shell's gate about what a *front end* does itself.
Package boundary asks a shell's gate about what a *front end* does itself.
cellgrid
Package cellgrid turns what a terminal was sent into what it would be showing: a grid of cells, each with the grapheme in it and the appearance it is drawn under.
Package cellgrid turns what a terminal was sent into what it would be showing: a grid of cells, each with the grapheme in it and the appearance it is drawn under.
charset
Package charset writes a code point as the byte a single-byte locale charset stands it in.
Package charset writes a code point as the byte a single-byte locale charset stands it in.
charsetgen command
Command charsetgen turns Unicode's character-mapping tables into the single-byte charsets a locale can name.
Command charsetgen turns Unicode's character-mapping tables into the single-byte charsets a locale can name.
childguard
Package childguard fails a test binary that leaves a process behind whose command line names a marker the caller chooses.
Package childguard fails a test binary that leaves a process behind whose command line names a marker the caller chooses.
cmd/acpcheck command
Command acpcheck drives the shell's Agent Client Protocol front end the way an editor would — as a subprocess, over JSON-RPC on a pipe — and prints what works, what it cost, and what an ordinary pipe would have seen instead.
Command acpcheck drives the shell's Agent Client Protocol front end the way an editor would — as a subprocess, over JSON-RPC on a pipe — and prints what works, what it cost, and what an ordinary pipe would have seen instead.
cmd/axissweep command
Command axissweep moves every axis in interp.Semantics and reports the ones nothing objected to.
Command axissweep moves every axis in interp.Semantics and reports the ones nothing objected to.
cmd/corpusguard command
Command corpusguard fails when the oracle corpus has lost a case.
Command corpusguard fails when the oracle corpus has lost a case.
cmd/coverage command
Command coverage reports, per dialect, every element of the shell's surface that no case in the tree mentions.
Command coverage reports, per dialect, every element of the shell's surface that no case in the tree mentions.
cmd/diagsample command
Command diagsample runs one bounded sample of error situations through a real shell and through ours, and reports how many came back byte-identical.
Command diagsample runs one bounded sample of error situations through a real shell and through ours, and reports how many came back byte-identical.
cmd/emulatesweep command
Command emulatesweep reports how far `emulate MODE` reaches into the grammar, by asking every corpus snippet whether the three modes disagree about it.
Command emulatesweep reports how far `emulate MODE` reaches into the grammar, by asking every corpus snippet whether the three modes disagree about it.
cmd/fmtwild command
Command wild formats every shell script it can find and holds each result to the formatter's three promises: the tree survives, the comments survive, and a second pass changes nothing.
Command wild formats every shell script it can find and holds each result to the formatter's three promises: the tree survives, the comments survive, and a second pass changes nothing.
cmd/histprobe command
Command histprobe drives a shell through a pseudo-terminal with a TWO-ROW prompt and types lines at it one at a time, waiting on a distinct done-marker after each.
Command histprobe drives a shell through a pseudo-terminal with a TWO-ROW prompt and types lines at it one at a time, waiting on a distinct done-marker after each.
cmd/oracle command
Command oracle records what real shells do, and fails when that changes.
Command oracle records what real shells do, and fails when that changes.
cmd/oraclerunner command
Command oraclerunner is the oracle harness, inside a container.
Command oraclerunner is the oracle harness, inside a container.
cmd/promptfidelity command
Command promptfidelity compares the prompt this shell draws with the prompt the program a configuration was imported from draws.
Command promptfidelity compares the prompt this shell draws with the prompt the program a configuration was imported from draws.
cmd/sandboxcheck command
Command sandboxcheck grades the boundary from outside the process: it runs the shell that ships, tries every way a script has of reaching the filesystem, and asks the filesystem what happened.
Command sandboxcheck grades the boundary from outside the process: it runs the shell that ships, tries every way a script has of reaching the filesystem, and asks the filesystem what happened.
cmd/smoke command
Command smoke drives a realistic interactive session through a real terminal, for each dialect binary it is given, and prints what worked.
Command smoke drives a realistic interactive session through a real terminal, for each dialect binary it is given, and prints what worked.
cmd/suitecheck command
Command suitecheck fetches a shell's own test suite and runs every file of it through both that shell and the dialect binary claiming to be it.
Command suitecheck fetches a shell's own test suite and runs every file of it through both that shell and the dialect binary claiming to be it.
cmd/suiteguard command
Command suiteguard fails when our own conformance suite has lost a file or shrunk one.
Command suiteguard fails when our own conformance suite has lost a file or shrunk one.
cmd/suiteinside command
Command suiteinside is the half of `make suite` that runs inside a container image, for the one column whose reference shell exists nowhere else.
Command suiteinside is the half of `make suite` that runs inside a container image, for the one column whose reference shell exists nowhere else.
cmd/tworowprobe command
Command tworowprobe drives a dialect binary through a pseudo-terminal with a two-row prompt and reports what reached the screen.
Command tworowprobe drives a dialect binary through a pseudo-terminal with a two-row prompt and reports what reached the screen.
cmd/viprobe command
Command viprobe types one key sequence into one shell through a pseudo-terminal and prints the line that came back.
Command viprobe types one key sequence into one shell through a pseudo-terminal and prints the line that came back.
cmd/wild command
Command wild parses the shell scripts installed on this machine and reports the ones this parser cannot read.
Command wild parses the shell scripts installed on this machine and reports the ones this parser cannot read.
corpusguard
Package corpusguard checks that the oracle corpus never loses a case.
Package corpusguard checks that the oracle corpus never loses a case.
coverage
Package coverage asks what a body of shell cases never mentions.
Package coverage asks what a body of shell cases never mentions.
depsurface
Package depsurface has no code.
Package depsurface has no code.
dialecttest
Package dialecttest builds the interp.Runner a dialect package's own tests run their snippets on.
Package dialecttest builds the interp.Runner a dialect package's own tests run their snippets on.
eastasian
Package eastasian answers whether a code point is East Asian Width W or F, which is the one thing two readers of it have to agree about.
Package eastasian answers whether a code point is East Asian Width W or F, which is the one thing two readers of it have to agree about.
emulatesweep
Package emulatesweep measures how far `emulate MODE` reaches into the grammar, by asking every corpus snippet whether the three modes disagree about it.
Package emulatesweep measures how far `emulate MODE` reaches into the grammar, by asking every corpus snippet whether the three modes disagree about it.
event
Package event writes an interpreter's event stream down in a stable, front-end-neutral form.
Package event writes an interpreter's event stream down in a stable, front-end-neutral form.
fdset
Package fdset asks the kernel which descriptors a read would not wait on.
Package fdset asks the kernel which descriptors a read would not wait on.
fmt/comments
Package comments recovers the comments the substrate's parser discards.
Package comments recovers the comments the substrate's parser discards.
fmt/diff
Package diff renders a unified diff between two texts, for the formatter's -d mode.
Package diff renders a unified diff between two texts, for the formatter's -d mode.
fmt/printer
Package printer lays out a parsed script one way.
Package printer lays out a parsed script one way.
fmt/walk
Package walk visits every node of a github.com/blairham/sh syntax tree.
Package walk visits every node of a github.com/blairham/sh syntax tree.
fswatch
Package fswatch says when a directory has changed, without asking.
Package fswatch says when a directory has changed, without asking.
gateguard
Package gateguard reads a protocol front end's source and says, per served method, whether it reaches the boundary.
Package gateguard reads a protocol front end's source and says, per served method, whether it reaches the boundary.
histexpand
Package histexpand rewrites a line the way a shell's history expander does: `!!` becomes the previous command, `!$` its last word, `^old^new^` the previous command with one word changed.
Package histexpand rewrites a line the way a shell's history expander does: `!!` becomes the previous command, `!$` its last word, `^old^new^` the previous command with one word changed.
histjoin
Package histjoin makes one history entry out of the physical lines of one command.
Package histjoin makes one history entry out of the physical lines of one command.
lineread
Package lineread takes one line at a time off a descriptor that is shared with whatever reads it next, leaving the rest where that reader finds it.
Package lineread takes one line at a time off a descriptor that is shared with whatever reads it next, leaving the rest where that reader finds it.
mcp
Package mcp serves the Model Context Protocol, as a server, over stdio.
Package mcp serves the Model Context Protocol, as a server, over stdio.
mcpboot
Package mcpboot supplies driver.Shell.ServeMCP.
Package mcpboot supplies driver.Shell.ServeMCP.
normgen command
Command normgen turns Unicode's UnicodeData.txt into the tables internal/unorm decomposes with, and NormalizationTest.txt into the fixture that proves it agrees with Unicode.
Command normgen turns Unicode's UnicodeData.txt into the tables internal/unorm decomposes with, and NormalizationTest.txt into the fixture that proves it agrees with Unicode.
opened
Package opened answers the one question a name-based gate cannot answer for itself: what path did this open actually go through?
Package opened answers the one question a name-based gate cannot answer for itself: what path did this open actually go through?
oracle
Package oracle records what real shells do.
Package oracle records what real shells do.
panicguard
Package panicguard turns a panic raised while running a script into an ordinary diagnostic.
Package panicguard turns a panic raised while running a script into an ordinary diagnostic.
parsecache
Package parsecache keeps the trees of the files a shell sources from one run of it to the next (#6424): a Reader that answers a file's reads from the cache while what the cache recorded still holds, and a Store that keeps the entries on disk, under `$XDG_CACHE_HOME/sh/parse` or `~/.cache/sh/parse`.
Package parsecache keeps the trees of the files a shell sources from one run of it to the next (#6424): a Reader that answers a file's reads from the cache while what the cache recorded still holds, and a Store that keeps the entries on disk, under `$XDG_CACHE_HOME/sh/parse` or `~/.cache/sh/parse`.
pgo
Package pgo holds the programs the shipped binaries' build profile is trained on, and nothing else.
Package pgo holds the programs the shipped binaries' build profile is trained on, and nothing else.
plugin
Package plugin runs a builtin whose implementation is in another process, in whatever language its author chose.
Package plugin runs a builtin whose implementation is in another process, in whatever language its author chose.
policy
Package policy is a declarative interp.Gate: a set of rules over paths and action kinds, and a default for everything they do not mention.
Package policy is a declarative interp.Gate: a set of rules over paths and action kinds, and a default for everything they do not mention.
preludegen command
Command preludegen writes each dialect's parsed prelude into the dialect's package as a Go literal, so a shell starts with the tree already built rather than parsing the same text on every start (#6397).
Command preludegen writes each dialect's parsed prelude into the dialect's package as a Go literal, so a shell starts with the tree already built rather than parsing the same text on every start (#6397).
promptfidelity
Package promptfidelity compares the prompt this shell draws with the prompt the program it was imported from draws.
Package promptfidelity compares the prompt this shell draws with the prompt the program it was imported from draws.
promptimport
Package promptimport converts another prompt program's configuration into this one's.
Package promptimport converts another prompt program's configuration into this one's.
prompttheme
Package prompttheme is the prompt theme engine's configuration vocabulary: the keyed store a theme is written in, the lookup that resolves a setting for a segment, the colors a setting may name, and the markup a value may carry.
Package prompttheme is the prompt theme engine's configuration vocabulary: the keyed store a theme is written in, the lookup that resolves a setting for a segment, the colors a setting may name, and the markup a value may carry.
pty
Package pty opens a pseudo-terminal pair, so that a test can hand a shell a real terminal.
Package pty opens a pseudo-terminal pair, so that a test can hand a shell a real terminal.
repostatus
Package repostatus answers what repository the shell is standing in, from a resident cache that a filesystem watch keeps honest.
Package repostatus answers what repository the shell is standing in, from a resident cache that a filesystem watch keeps honest.
sandboxcheck
Package sandboxcheck grades the boundary from outside the process, by running the binary that ships and asking the filesystem what happened.
Package sandboxcheck grades the boundary from outside the process, by running the binary that ships and asking the filesystem what happened.
secret
Package secret finds credentials in text.
Package secret finds credentials in text.
smoke
Package smoke drives a realistic interactive session through a real terminal and reports, feature by feature, what worked.
Package smoke drives a realistic interactive session through a real terminal and reports, feature by feature, what worked.
startupcost
Package startupcost measures how long a shell takes to become useful.
Package startupcost measures how long a shell takes to become useful.
suite
Package suite runs a real shell's own test suite through both that shell and the dialect binary that claims to be it, and reports where they part.
Package suite runs a real shell's own test suite through both that shell and the dialect binary that claims to be it, and reports where they part.
suiteguard
Package suiteguard checks that our own conformance suite never loses a file or shrinks one.
Package suiteguard checks that our own conformance suite never loses a file or shrinks one.
termhost
Package termhost runs commands for a protocol peer and keeps them as handles.
Package termhost runs commands for a protocol peer and keeps them as handles.
terminfofixture
Package terminfofixture builds compiled terminal descriptions for tests.
Package terminfofixture builds compiled terminal descriptions for tests.
testenv
Package testenv gives a test suite that starts shells an environment of its own, assembled from nothing rather than inherited from whoever ran `go test`.
Package testenv gives a test suite that starts shells an environment of its own, assembled from nothing rather than inherited from whoever ran `go test`.
treecodec
Package treecodec writes a parsed program out as bytes and reads it back as the same tree, for the parse cache (#6424).
Package treecodec writes a parsed program out as bytes and reads it back as the same tree, for the parse cache (#6424).
treeguard
Package treeguard fails a test binary that leaves a file behind in the directory it ran in.
Package treeguard fails a test binary that leaves a file behind in the directory it ran in.
tty
Package tty answers one question: is this open file a terminal.
Package tty answers one question: is this open file a terminal.
unorm
Package unorm answers whether two strings are the same text, which is not the same question as whether they are the same bytes.
Package unorm answers whether two strings are the same text, which is not the same question as whether they are the same bytes.
widthgen command
Command widthgen turns Unicode's EastAsianWidth.txt into the table the line editor measures with.
Command widthgen turns Unicode's EastAsianWidth.txt into the table the line editor measures with.
wild
Package wild sweeps the shell scripts installed on the machine and reports which of them this parser cannot read — and which of them it reads where the reference shell will not.
Package wild sweeps the shell scripts installed on the machine and reports which of them this parser cannot read — and which of them it reads where the reference shell will not.
Package interp executes a syntax tree.
Package interp executes a syntax tree.
Package repl is the interactive surface: a prompt, a line editor, and the loop between them.
Package repl is the interactive surface: a prompt, a line editor, and the loop between them.
Package syntax turns shell source into tokens and a syntax tree.
Package syntax turns shell source into tokens and a syntax tree.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL