absd-sh(1)

MILESTONE-QUALIFIED Rendered from the page's mdoc source at milestone/general-usability-qemu-20260927 (platform ff025b1) with GNU groff version 1.23.0, using the same command the image build uses; an ABSD session running man 1 absd-sh prints this text. It is dated 2026-09-27; the build commands and repository files it mentions are in private sources, and later work is not in it. All pages.

ABSD-SH(1)                  General Commands Manual                 ABSD-SH(1)

NAME
       absd-sh -- the ABSD command shell

SYNOPSIS
       absd-sh [-c line]

DESCRIPTION
       absd-sh reads one line at a time and runs it as one pipeline.  Without
       arguments it writes the prompt `absd$ ' before every line, and at the
       end of its input exits with the status of the last line.  With -c it
       runs line and exits with its status.  It is the shell an interactive
       SSH session starts.  It is deliberately small: it is not a POSIX shell
       and does not run scripts.

       A command given to ssh (`ssh host ls /bin') does not run under absd-sh:
       the SSH server splits it at whitespace, with no quoting, pipes, or
       redirection, and runs its first word directly (a bare name as
       /bin/name).  To run a pipeline without a terminal, write the lines to
       the shell's standard input: `echo 'ls /bin | wc -l' | ssh host'.

   Words
       A line splits into words at whitespace.  Double quotes group: `"a b"'
       is one word, and `a"b c"' is the word `ab c'.  Inside quotes, `\"' and
       `\\' stand for `"' and `\', and `|', `<', `>' are ordinary characters.
       Outside quotes a backslash is an ordinary character.  Nothing else is
       special: `$', `*', `~', `;', `&', and `#' are ordinary characters, so
       there are no variables, no globbing, no command lists, and no comments.
       An unterminated quote is a syntax error.

   Commands
       The first word names the command.  The builtins are listed below.  Any
       other name runs a program from the filesystem: the word itself when it
       contains a `/', resolved against the working directory, otherwise
       /bin/name.  There is no PATH search.  A program is a static ABSD
       executable; there is no `#!' and no execute permission.  The remaining
       words are its arguments.  It starts with the shell's working directory
       and environment, and with any of its three standard streams that is not
       piped or redirected shared with the shell.

   Pipelines and redirection
       Commands joined by `|' run at the same time, each one's standard output
       feeding the next one's standard input through a kernel pipe.  When a
       reader ends first, the writer's next write fails with a broken pipe
       error; there is no signal.  A pipeline's status is its last command's.

       Each command may redirect its streams:
       < file    standard input from file
       > file    standard output to file, created or truncated
       >> file   standard output appended to file
       2> file   standard error to file
       2>> file  standard error appended to file

       The shell opens every redirection itself, with its own authority,
       before anything starts; if one cannot be opened nothing starts and the
       status is 1.  The command never holds the file: its stream is a pipe,
       and the shell copies between the pipe and the file.

       These are syntax errors (status 2, nothing starts): an empty command in
       a pipeline, a redirection without a file name, the same stream
       redirected twice, output both to a file and into a pipe, input both
       from a file and from a pipe, and descriptor duplication such as `2>&1'.

   Narrowing a command's authority
       By default a started command gets the shell's filesystem authority: a
       file server channel bound to the shell's own mounts, never more.  Two
       prefixes narrow it for one command:
       ro command ...
                 the same mounts, all read-only
       nofs command ...
                 no filesystem at all

       A command started this way still writes its standard output and error;
       `ro cmd > file' writes file through the shell, while cmd itself cannot
       write anywhere.  The prefixes apply to programs, not to builtins.

       Each command needs a file server channel of its own: one of the shell's
       spare channels (at most two, fewer while other sessions are open), or,
       for one command at a time, the shell's own channel lent to it.  ro and
       nofs need a spare, and so does every command while the shell is copying
       a redirection.  A command that gets no channel is not started (status
       126).  See "CAVEATS".

   Builtins
       cd [dir]  Change the working directory to dir, which must be an
                 existing directory the session can see; without dir, to /.

       pwd       Print the working directory.

       echo [word ...]
                 Print the words separated by single spaces.

       status    Print the status of the last line.

       exit [n]  Exit with status n, or with the last status.

       ps        List this session's processes; see ps(1).

       shutdown [-h | -p | -r now]
                 Ask sshd to halt the machine, or with -r to restart it; see
                 shutdown(8).

       reboot    Ask sshd to restart the machine; see reboot(8).

       ps, shutdown, and reboot are requests to the SSH server on the
       session's control channel, which only a shell sshd started for an
       interactive session holds; any other absd-sh answers `no session
       control channel' with status 1.

       pwd, echo, status, and ps may start a pipeline (the shell writes their
       output into the next command) and may take >, >>, and 2>.  cd, exit,
       shutdown, and reboot cannot be part of a pipeline.

   Diagnostics and status
       When the last command of a line exits with a nonzero status the shell
       reports `absd-sh: name: exit status n'.  The statuses the shell itself
       assigns:
       1    a redirection could not be opened or completed
       2    a syntax error, or a builtin used wrongly
       126  the program was found but could not be started
       127  the program was not found
       128  the program ended without an exit status (it faulted or was
            killed)
       130  the line was interrupted with ^C (nothing more is printed)

   On a terminal
       With a terminal (`ssh -t'), or plain `ssh host', the SSH server, not
       the shell, echoes and edits the line: DEL or BS erases a character, ^U
       the line, and ^C discards the line being typed.

       ^C while a line runs interrupts it.  The key never reaches the
       command's input: the SSH server tells the shell on the session's
       control channel, and the shell kills every command of the running
       pipeline with the process handle it holds, waits for them, and prompts
       again; the line's status is 130.  What a command wrote to a redirection
       file before it was killed stays there.  The shell looks for ^C between
       bounded waits on its commands, so it acts within a few milliseconds of
       the SSH server passing it on.  A ^C typed at the prompt only discards
       the line; it does not interrupt the next command.  A line holds at most
       4095 bytes.  ^D on an empty line ends input for the whole session: a
       command reading standard input sees end of file, and so does the shell,
       which then exits.  Standard output and standard error arrive on the one
       screen, in the order written.  The terminal type and window size are
       not used.

EXAMPLES
             absd$ cat /etc/motd | wc -l
             1
             absd$ ls /home/operator > /home/operator/listing
             absd$ ro cp /etc/motd /home/operator/copy
             cp: /etc/motd -> /home/operator/copy: ABSD filesystem is mounted read-only
             absd-sh: cp: exit status 1
             absd$ nofs df
             df: this process has no file server channel (-2)
             absd-sh: df: exit status 1

SEE ALSO
       intro(1), ps(1), filesystem(7), handles(7), process(7), reboot(8),
       shutdown(8)

CAVEATS
       ^C ends the commands the shell started, not what they started in turn:
       there is no process-tree kill.  A command that itself started programs
       (another absd-sh, for instance) leaves them running when it is
       interrupted; they are adopted by init, keep the session's input,
       output, and filesystem channel until they end, and may take lines typed
       at the prompt.  ps(1) counts them.  Without a terminal (`ssh -T') there
       is no ^C.

       Ending the SSH connection ends the shell; its running commands lose
       their standard streams and their filesystem authority, and run to their
       own end.

       How many commands of one pipeline can hold a file server channel at
       once depends on how many sessions are open; there is no fixed number to
       rely on beyond two.

       Standard input is shared with the shell, but lines the shell has
       already read are not visible to a command.

BUGS
       There are no globbing, variables, command lists (`;' and `&&'),
       descriptor duplication, job control, here-documents, or scripts.

ABSD                          September 27, 2026                    ABSD-SH(1)

All manual pages