Built-in commands compared

This page lists every built-in command of dash, bash, zsh and luish, and for those luish lacks, what to use instead. It complements luish, dash, bash and zsh; Built-in commands documents luish’s own built-ins in full.

The lists are those of dash 0.5.12 (Debian and Ubuntu’s), bash 5.2 (compgen -b), zsh 5.9 (${(k)builtins} with no startup files, which includes the built-ins of modules zsh loads on demand, such as zstyle and the completion system’s) and luish 0.7.0. zsh’s other modules, loaded with zmodload (such as zsh/files, zsh/datetime or zsh/system), add more, and bash can load more with enable -f; those are not listed.

dash

bash

zsh

luish

Built-ins

38

61

103

54, and 8 more in interactive shells

In the tables, ✓ marks a built-in, – its absence, and i a built-in that luish has only in interactive shells (and their subshells), so that scripts find the same commands as under dash; there, __luish_internal NAME runs it.

POSIX special built-ins

All four shells have these. As POSIX requires, an error in a special built-in exits a non-interactive shell, and assignments before one stay set; luish follows dash in both.

Built-in

dash

bash

zsh

luish

luish compared with bash and zsh

:

✓

✓

✓

✓

.

✓

✓

✓

✓

Further arguments are the positional parameters while the file runs, as in bash and zsh

break

✓

✓

✓

✓

continue

✓

✓

✓

✓

eval

✓

✓

✓

✓

exec

✓

✓

✓

✓

No -a, -c or -l

exit

✓

✓

✓

✓

export

✓

✓

✓

✓

Takes arrays (export a=(x y) sets and exports a); no -n or -f (bash)

readonly

✓

✓

✓

✓

Takes arrays; no -f (bash)

return

✓

✓

✓

✓

set

✓

✓

✓

✓

POSIX’s options, with -o pipefail; luish’s own and zsh-named options go through setopt (or -o NAME)

shift

✓

✓

✓

✓

times

✓

✓

✓

✓

trap

✓

✓

✓

✓

Signals and EXIT; no ERR, DEBUG or RETURN (bash), ZERR or TRAP* functions (zsh), and no -p or -l

unset

✓

✓

✓

✓

-f and -v; elements of arrays (unset 'a[1]')

POSIX regular built-ins and utilities

The commands that POSIX requires to be built in (alias, bg, cd, command, fc, fg, getopts, hash, jobs, kill, read, type, ulimit, umask, unalias, wait), and the utilities that shells build in for speed.

Built-in

dash

bash

zsh

luish

luish compared with bash and zsh

[, test

✓

✓

✓

✓

POSIX’s operators, as dash; -v NAME only in [[ ... ]]

alias

✓

✓

✓

✓

zsh’s options (-g and -s for global and suffix aliases, -r, -m, -L, +); no -p (bash)

bg

✓

✓

✓

✓

cd

✓

✓

✓

✓

-L, -P, -e, cd -, CDPATH, and zsh’s auto_pushd; no cd OLD NEW (zsh)

command

✓

✓

✓

✓

-p, -v, -V

echo

✓

✓

✓

✓

As dash’s: escapes such as \t are always interpreted, and -n is the only option (bash needs -e; zsh interprets them unless BSD_ECHO is set)

false, true

✓

✓

✓

✓

fc

– [1]

✓

✓

✓

-e, -l, -n, -r, -s; no times (zsh’s -d, -i) or zsh’s other options

fg

✓

✓

✓

✓

getopts

✓

✓

✓

✓

hash

✓

✓

✓

✓

-r; no -d, -p, -t, -l. Rarely needed: luish clears the cache itself when a PATH directory changes

jobs

✓

✓

✓

✓

-l, -p, and -i, a menu to act on the jobs; no -r, -s, -n, -x

kill

✓

✓

✓

✓

-s, -SIGNAL, -l, and jobs (%1)

printf

✓

✓

✓

✓

%b; no -v or %q

pwd

✓

✓

✓

✓

-L, -P

read

✓

✓

✓

✓

-r, -p, and arrays with -a (bash) or -A (zsh); no -t, -n, -s, -d, -u, -e or zsh’s -k, -q

type

✓

✓

✓

✓

No options (bash’s -a, -t, -p; zsh’s -a, -w …); names the plugin of a built-in that a plugin added

ulimit

✓

✓

✓

✓

-H, -S, -a and dash’s resource letters

umask

✓

✓

✓

✓

-S

unalias

✓

✓

✓

✓

-a, and zsh’s -m, -s

wait

✓

✓

✓

✓

Jobs and process ids; no -n, -f or -p (bash)

Common extensions

Built-ins outside POSIX that luish has, mostly as zsh has them.

Built-in

dash

bash

zsh

luish

Notes

bindkey

–

–

✓

i

zsh’s, for the emacs keymap and the widgets luish has; keys can also be named (Up, Ctrl-Right). No other keymaps (-M) and no user-defined widgets

builtin

–

✓

✓

✓

caller

–

✓

–

✓

bash’s

chdir

✓

–

✓

✓

The same as cd

declare, typeset

–

✓

✓

✓

-a, -A, -f, -g, -i, -l, -p, -r, -u, -U, -x, and +f; no namerefs (bash’s -n), floating point (zsh’s -E, -F), padding (zsh’s -L, -R, -Z), -t or tied variables (zsh’s -T)

disown

–

✓

✓

✓

As in zsh, with bash’s -a, -r and -h, and process ids

dirs, pushd, popd

–

✓

✓

✓

As in zsh: -q, -L, -P, +n, -n; dirs -l, -p, -v, -c

help

–

✓

–

i

Help for luish’s built-ins, from the pages in Built-in commands

let

–

✓

✓

✓

As in zsh; integers only

local

✓

✓

✓

✓

Special, as in dash. Takes typeset’s options and arrays (local a=(x y)). Without a value, keeps the outer value, as in dash (in bash and zsh it starts unset or empty)

print

–

–

✓

i

zsh’s, with its options except -p (no coprocesses) and -S

setopt, unsetopt

–

–

✓

✓

zsh’s names for the options luish has, and luish’s grouped names (history.share) and NAME=VALUE settings

shopt

–

✓

–

✓

bash’s, setting luish’s options that do the same (glob.star for globstar); the options luish lacks can’t be set

source

–

✓

✓

✓

As in zsh: a name without / is looked for in the current directory first

vared

–

–

✓

i

zsh’s, without its widget options (-i, -f) and -t

Built-ins that luish lacks

In both bash and zsh

Built-in

What it does

In luish

enable (zsh’s also disable)

Turn built-ins off or on

command NAME or a full path runs the program instead

history

List the history

fc -l

logout

Exit a login shell

exit

suspend

Stop the shell

kill -STOP $$

bash only

Built-in

What it does

In luish

bind

readline key bindings

bindkey, or [bindkey] in config.toml

compgen, complete, compopt

Programmable completion

Completers in Rhai, from plugins; std.bash-completion runs bash’s completion scripts

mapfile, readarray

Read lines into an array

A loop: while IFS= read -r l; do a+=("$l"); done

zsh only

Built-in

What it does

In luish

-

Run a command as a login shell would (argv[0] with -)

None

autoload

Define a function to be loaded from fpath on first use

None: . the file in a startup file, which the startup cache makes cheap

bye

Exit

exit

compadd, comparguments, compcall, compdescribe, compfiles, compgroups, compquote, compset, comptags, comptry, compvalues

The completion system (compsys)

Completers in Rhai, from plugins

compctl

The old completion system

As above

echotc, echoti

Terminal capabilities

tput

emulate

Emulate sh, ksh or csh

None: luish is always an sh

float, integer

Floating-point and integer variables

typeset -i for integers; no floating point

functions

List or define functions

typeset -f

getln, pushln

The buffer stack

None

limit, unlimit

csh-style resource limits

ulimit

log

Report logins and logouts (watch)

None

noglob

Run a command without globbing

set -f, or quoting

private

Variables not seen by called functions

local (seen by called functions)

r

Re-run a command

fc -s (alias r='fc -s')

rehash

Clear the command cache

Rarely needed (automatic); hash -r

sched

Run commands at a given time

None

ttyctl

Freeze the terminal’s settings

None

unfunction, unhash

Remove functions, aliases or cached commands

unset -f, unalias, hash -r

whence, where, which

Describe or find commands

type, command -v, command -V. luish’s own where shows where variables were set

zcompile

Compile scripts

None needed for startup files: the startup cache saves their effect

zformat, zparseopts, zregexparse

Formatting and parsing helpers

printf, getopts, [[ =~ ]]

zle

Line editor widgets

bindkey binds keys to luish’s widgets; no user-defined widgets

zmodload

Load modules

Plugins, with extensions in Rhai that can add commands

zstyle

Style settings, mostly for completion

Settings in config.toml and setopt NAME=VALUE

luish’s own

Built-in

What it does

__luish_internal

Subcommands that are not needed often: check-cache (check the startup cache), savestate (print commands that restore the shell’s state), complete (show what Tab would offer), print-git-rev, and the interactive-only built-ins, which work there in scripts too

clipcopy (i)

Put text on the clipboard, through the terminal

plugin (i)

Load, list, add, fetch and update plugins

style (i)

Set or show the styles and colour schemes of the line editor

where (i)

Show where variables were set, with setopt vars.trace (also in scripts, while variables are traced)

Plugins can add further built-ins, written in Rhai (see Extensions).

Reserved words

Some commands that look like built-ins are reserved words, parsed with the command.

Word

dash

bash

zsh

luish

Notes

!, { }, case, for, if, until, while …

✓

✓

✓

✓

POSIX

[[ ]]

–

✓

✓

✓

function

–

✓

✓

✓

time

–

✓

✓

–

Runs the time program instead, which can’t time pipelines or shell functions

select

–

✓

✓

–

coproc

–

✓

✓

–

repeat, foreach, nocorrect

–

–

✓

–

declare, export, local, readonly, typeset, float, integer

–

–

✓

–

In zsh, these are reserved words so that local a=(x y) parses. luish parses such array assignments for its own built-ins, which remain built-ins