[Toybox] toybox shell: alias support
Rob Landley
rob at landley.net
Wed Feb 11 13:21:44 PST 2026
On 2/11/26 01:16, Kevin Karhan wrote:
> As [hinted by Rob](https://mstdn.jp/@landley/116043106074437957) I'd
> like to add some test cases for aiias support in toybox's shell.
>
> - I mostly truncated [my public .bash_aliases file](https://github.com/
> kkarhan/misc-scripts/blob/master/bash/.bash_aliases), ditching external
> tools like enc and rewriting it to use wget instead of curl (because a
> wget implementation is part of toybox).
Which is good, but not quite the same as "tests". Your first one sets a
"clr" alias, and then you don't have anything that uses it. That said,
they seem obvious enough I can probably convert them myself.
I checked for documentation to point you at about the toybox test
suite... and I need to write more documentation. I ALWAYS need to write
more documentation. https://landley.net/toybox/faq.html#code isn't
nearly enough of an intro to the test suite. and
https://landley.net/toybox/code.html#infrastructure has a #tests link
that doesn't even go anywhere! Great...
Right: the toybox test suite ("make test_sh" in this case) is a bunch of
files in tests/*.test (one per command) with one-per-line tests, and
then the driver scripts are scripts/test.sh calling scripts/runtest.sh.
The one you DON'T run directly is scripts/runtest.sh which contains all
the guts of the test plumbing, the main part being the "testing" and
"testcmd" shell functions which run an actual test. Their arguments are
explained starting at scripts/runtest.sh line 15. (The second is a
convenience wrapper for the first.)
The other one (scripts/test.sh) is called directly, providing a command
line UI that either tests a single command (ala: scripts/test.sh sed) or
tests all the commands if run with no arguments. It does this by
creating "generated/testdir" (all toybox intermediate build files go in
generated/ so half of clean is just "rm -rf generated" and the rest is
deleting the final output files produced at the top level), plonking the
appropriate binary to be tested in there, sticking it at the start of
the $PATH, and then making an empty generated/testdir/testdir under that
to cd into and run all the tests in sequence in an empty scratch dir. If
you run it twice it'll rm -rf generated/testdir at the start so it sets
up a clean environment each time.
Android doesn't use test.sh, it only uses runtest.sh and creates its own
environment for it as part of the AOSP plumbing. (That's the main reason
they're two scripts, for integration into other projects' test suites.)
There are three main environment variables that modify how the tests get
run, two of which are described at the start of runtest.sh and the other
is mainly about how test.sh sets up the test environment:
TEST_HOST=1 - don't build a toybox binary, just test the existing
command out of the host $PATH.
DEBUG=1 - show every command run by every test script (you generally
don't want this unless you're doing development on the test suite itself).
VERBOSE=... - You can add multiple things here (ala VERBOSE=allnopass):
all - don't stop at the first FAIL, keep going until the end.
nopass - don't show PASS: lines, just failures
quiet - don't show diff -u between expected/actual output for failures
spam - show ALL THE OUTPUT (like DEBUG=1 above but for results)
The test suite also has a built in shell-based "expect" (the function
txpect() in scripts/runtest.sh starting line 182) which sh.tests then
wraps as shxpect() around line 19 so it can invoke the shell with:
env -i PATH=${PATH at Q} PS1='\\$ ' $SH --noediting --noprofile --norc -is
I.E. run in a clean environment (env -i), $SH runs sh or bash as
appropriate (toysh makes "sh" but /bin/sh is the Defective Annoying
SHell on ubuntu, not bash), and then some --longopts to beat testable
behavior out of bash. (without --noediting gnu/gnu/ftaghn/readline reads
from /dev/tty instead of stdin, yes really).
And then shxpect calls txpect but the first thing it does is wait for an
appropriate incoming interactive prompt on stderr and _then_ starts the
supplied challenge/response series.
You need to regression test alias this way because alias ONLY applies to
interactive input, it doesn't apply in shell scripts! (Which is just
nuts, but I didn't design it...)
In theory I added basic alias support in f43c79154259 and that had some
shxpect tests, and then updated it a bit in 8433c5d9a435 with more tests
(some about alias/unalias but mostly about prefix assignment).
Possibly the main thing missing here is that the startup logic doesn't
read .bash_aliases. If you source it yourself, which ones don't do what
you expect?
Rob
More information about the Toybox
mailing list