When you enter command sxx without arguments in the Windows Terminal window (wt.exe), the sxx virtual machine starts a System X shell session.
The command sxx sh --debug starts the shell in debug mode. When in debug mode, the token expansion information and command line parsing results are printed to the terminal along with the command output.
When you type a command line in the shell and press ENTER, the shell
First the command line is chopped into tokens consisting of meta-characters and series of other characters classified as tokens. The following table lists the tokenization rules:
rule name | rule content | token name | |
---|---|---|---|
sep | → | space | tab | SEPARATOR |
space | → | ' ' | SPACE |
tab | → | '\t' | TAB |
quoted-char | → | '\\' any | QUOTED_CHAR |
single-quoted | → | \'[^']*\' | SINGLE_QUOTED |
double-quoted | → | \"[^"]*\" | DOUBLE_QUOTED |
and-if | → | && | AND_IF |
or-if | → | || | OR_IF |
dsemi | → | ;; | DSEMI |
dlessdash | → | <<- | DLESSDASH |
dless | → | << | DLESS |
dgreat | → | >> | DGREAT |
lbrace | → | { | LBRACE |
rbrace | → | } | RBRACE |
bang | → | ! | BANG |
pipe | → | | | PIPE |
lparen | → | ( | LPAREN |
rparen | → | ) | RPAREN |
less-and | → | <& | LESSAND |
great-and | → | >& | GREATAND |
less-great | → | <> | LESSGREAT |
clobber | → | >| | CLOBBER |
less | → | < | LESS |
great | → | > | GREAT |
amp | → | & | AMP |
semi | → | ; | SEMI |
back-quote | → | ` | BACKQUOTE |
token | → | [^ \t\\'\"&|;<>{}`]+ | TOKEN |
word | → | token | WORD |
The backslash character quotes the character coming after it. A token enclosed in apostrophes quotes the enclosed characters. A token enclosed in double quotes the enclosed characters. Tokens containing quotation are not subject to token expansions. Exception to this is the filename expansion, in which backslash-quoted characters are included in the filename.
After tokenization the tokens are expanded using the following expansions:
In brace expansion the tokens are grouped to form brace expressions consisting of
These groups are separated by sep tokens.
The expansion is purely textual.
command | prints |
---|---|
echo a{c,p,t}e ate all the bananas | ace ape ate all the bananas |
echo file{.txt,.bak,.log} | file.txt file.bak file.log |
In tilde expansion tokens starting with a tilde character ('~') are expanded as follows:
command | prints |
---|---|
echo ~ | /home/seppo |
echo ~/foo | /home/seppo/foo |
echo ~root | / |
echo ~root/bin | /bin |
When a token contains an unquoted dollar character ($), the token is subject to parameter expansion.
The parameter expansion expands a name of an environment variable to the value of that environment variable.
The name of the parameter can be optionally enclosed in braces.
command | prints |
---|---|
echo $PATH | /bin |
echo ${SHELL} | /bin/sh |
When a token contains a pattern character '*', '?' or '[', the token containing the pattern is expanded into path tokens containing filenames found in the path prefix before the pattern.
command | prints |
---|---|
echo /etc/* | /etc/environment /etc/group /etc/passwd /etc/passwd_hash /etc/sudoers |
echo /mnt/sx/system/System.Lex/*.cm | /mnt/sx/system/System.Lex/ClassMap.cm /mnt/sx/system/System.Lex/Keyword.cm /mnt/sx/system/System.Lex/Lexeme.cm /mnt/sx/system/System.Lex/Lexer.cm /mnt/sx/system/System.Lex/ParsingException.cm /mnt/sx/system/System.Lex/ParsingLog.cm /mnt/sx/system/System.Lex/Span.cm /mnt/sx/system/System.Lex/Token.cm /mnt/sx/system/System.Lex/TrivialLexer.cm /mnt/sx/system/System.Lex/XmlParsingLog.cm |
The last token conversion phase is to remove quotation and to convert tokens into words.
After the tokens are expanded, the shell parses the expanded tokens into command objects according to the following grammar:
rule name | rule content | expression | |
---|---|---|---|
command-line | → | list separator? | |
list | → | and-or ( separator and-or )* | sequence |
separator | → | semi | |
and-or | → | pipeline ( and-if pipeline | or-if pipeline )* | and-or |
pipeline | → | bang? command (pipe command )* | pipeline |
command | → | simple-command | compound-command | |
simple‑command | → |
command-prefix
(command-name
command-suffix?
)? | command-name command-suffix? |
simple‑command |
command‑prefix | → | (io‑number? io‑file | assignment‑word)+ | |
command‑name | → | word | |
io‑number | → | word containing only digits | |
io‑file | → | less‑and filename | less filename | great‑and filename | great filename | dgreat filename | less‑great filename | clobber filename | I/O redirections |
filename | → | word | |
assignment‑word | → | word containing an assignment symbol (=) | assignment |
command‑suffix | → | (io‑number? io‑file | word)+ | |
compound‑command | → | brace‑group | subshell | |
brace‑group | → | lbrace command-line rbrace | brace-group |
subshell | → | lparen command-line rparen | subshell |
Execute a list of commands separated by the ; control operator. The exit code of the command list is the exit code of the last executed command.
command | prints |
---|---|
echo hot >meal; echo dog >>meal; cat meal | hot dog |
Execute command expressions separated by the && and || operators from left to right.
The left-command && right-command expression is executed so that the right-command is executed only if the exit code of the left-command is zero. The exit code of the command expression is the exit code of the left-command if it is nonzero, otherwise it is the exit code of the right-command.
command | prints |
---|---|
echo foo && echo bar | foo bar |
The left-command || right-command expression is executed so that the right-command is executed only if the exit code of the left-command is nonzero. The exit code of the command expression is the exit code of the right-command if the exit code of the left-command is zero, otherwise it is the exit code of the left-command.
command | prints |
---|---|
rm nonexistent || echo NOT REMOVED | System.SystemError: path 'nonexistent' not found... NOT REMOVED |
The shell executes the left-command | right-command expression by directing standard output of the left-command to standard input of the right-command. The shell waits the commands of the pipeline to terminate and then returns the exit code of the right-command as the exit code of the pipeline.
command | prints |
---|---|
cat /etc/environment | head --lines=1 | PATH="/bin" |
Executes the variable assignments and I/O redirections contained by the command-prefix and the I/O redirections of the command-suffix. Then if the simple command contains a command-name executes that command with arguments specified in the command-suffix.
command | prints |
---|---|
echo foo bar baz | foo bar baz |
NAME=VALUE | assign VALUE to the variable NAME in the command's environment; if simple-command contains no command-name, assigns VALUE to the variable NAME in the shell's environment |
command | prints |
---|---|
FOO=BAR | |
echo $FOO | BAR |
<filename | open 'filename' for reading and redirect its contents to command's standard input (file descriptor 0) |
N<filename | open 'filename' for reading and redirect its contents to command's file descriptor N |
>filename | open 'filename' with create, truncate, and write flags and redirect commmand's standard output (file descriptor 1) to it |
N>filename | open 'filename' with create, truncate, and write flags and redirect command's file descriptor N to it |
>>filename | open 'filename' for appending and redirect command's standard output (file descriptor 1) to it |
N>>filename | open 'filename' for appending and redirect command's file descriptor N to it |
command | prints |
---|---|
echo hot >meal | |
echo dog >>meal | |
cat meal | hot dog |
Executes the commands contained by the brace group in the current shell process.
Executes the commands contained by the subshell expression in the subshell child process of the current shell process.
The following table contains the commands built into the shell:
command | description | notes |
---|---|---|
cd [ARG] | changes current directory | if the cd command is invoked with a directory argument, changes the current directory to that directory, otherwise if the command is invoked without arguments, changes the current directory to the home directory of the current user. |
exit | exits the shell | |
printenv | prints the environment | |
unset ARG | removes an environment variable from the shell's environment | |
umask [THREE_DIGIT_OCTAL_NUMBER] | sets or prints the umask | if the umask command is invoked with an argument, changes the current umask to THREE_DIGIT_OCTAL_NUMBER for owner, group and others and prints the value of previous umask, otherwise if the command is invoked without arguments, prints the current umask. |