mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-22 12:35:14 +00:00
Shell: Start writing a man page
This patch adds two man pages describing the parts of the shell that have been so far finalised.
This commit is contained in:
parent
a2b99dd3ea
commit
0950fd1438
Notes:
sideshowbarker
2024-07-19 03:39:35 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/0950fd1438e Pull-request: https://github.com/SerenityOS/serenity/pull/2824 Reviewed-by: https://github.com/awesomekling Reviewed-by: https://github.com/bugaevc Reviewed-by: https://github.com/nico
3 changed files with 309 additions and 1 deletions
40
Base/usr/share/man/man1/Shell.md
Normal file
40
Base/usr/share/man/man1/Shell.md
Normal file
|
@ -0,0 +1,40 @@
|
|||
## Name
|
||||
|
||||
`Shell` - Shell, the command language interpreter
|
||||
|
||||
## Synopsis
|
||||
|
||||
```**sh
|
||||
$ Shell [--skip-shellrc]
|
||||
$ Shell [--skip-shellrc] command_file [arguments...]
|
||||
$ Shell [--skip-shellrc] -c command_string [arguments...]
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
The `Shell` utility is a command language interpreter, which reads commands from either a command string, a specified file, or the standard input.
|
||||
The command language shall be described in [`Shell`(5)](../man5/Shell.md), _The Shell Command Language_.
|
||||
|
||||
Any extra arguments passed into `arguments` are placed in the local variable `$ARGV` and can also be accessed through the special variable `$*`.
|
||||
|
||||
**NOTE**:
|
||||
|
||||
The `Shell` utility does not promise POSIX `sh` interoperability.
|
||||
|
||||
## Options
|
||||
|
||||
* `-c`, `--command-string`: Executes the given string as a command and exits
|
||||
* `--skip-shellrc`: Skips running the initialisation file (at `~/.shellrc`)
|
||||
|
||||
## Examples
|
||||
|
||||
```sh
|
||||
# Start an interactive REPL, ignoring the shellrc
|
||||
Shell --skip-shellrc
|
||||
|
||||
# Execute a given string
|
||||
Shell -c 'rm foo*'
|
||||
|
||||
# Execute the contents of a file with some arguments
|
||||
Shell foo a b c
|
||||
```
|
266
Base/usr/share/man/man5/Shell.md
Normal file
266
Base/usr/share/man/man5/Shell.md
Normal file
|
@ -0,0 +1,266 @@
|
|||
## Name
|
||||
|
||||
The Shell Command Language
|
||||
|
||||
## Introduction
|
||||
|
||||
The shell operates according to the following general steps:
|
||||
|
||||
* Some string is read from a source, be it a file, the standard input, or a command string (see [`Shell`(1)](../man1/Shell.md))
|
||||
* The shell parses the input to an abstract syntax tree
|
||||
* The shell performs various expansions and/or resolutions on the nodes
|
||||
* The shell performs various type checks and syntactic checks
|
||||
* The shell interprets the AST, evaluating commands as needed
|
||||
* For each given command, the shell flattens all the string/list arguments
|
||||
* For each given command, the shell records the applicable redirections
|
||||
* Should a command be executed, the shell applies the redirections, and executes the command with the flattened argument list
|
||||
* Should a command need waiting, the shell shall wait for the command to finish, and continue execution
|
||||
|
||||
Any text below is superceded by the formal grammar defined in the _formal grammar_ section.
|
||||
|
||||
## General Token Recognition
|
||||
|
||||
This section describes the general tokens the language accepts, it should be noted that due to nature of the language, some tokens are valid only in a specific context.
|
||||
|
||||
##### Bareword
|
||||
String of characters that are not _Special_ or _Syntactic Elements_
|
||||
|
||||
##### Glob
|
||||
String of characters containing at least one of `*?` in _bareword_ position
|
||||
|
||||
##### Single Quoted String
|
||||
Any sequence of characters between two single quotes (`'`)
|
||||
|
||||
##### Double Quoted String
|
||||
Any sequence of _Double Quoted String Part_ tokens:
|
||||
* Barewords
|
||||
* Single Quotes
|
||||
* Variable References
|
||||
* Evaluate expressions
|
||||
* Escaped sequences
|
||||
|
||||
##### Variable Reference
|
||||
Any sequence of _Identifier_ characters, or a _Special Variable_ follwing a `$`
|
||||
|
||||
##### Evaluate expression
|
||||
Any expression following a `$` that is not a variable reference:
|
||||
* Inline execution: A _syntactic list_ following a `$`:
|
||||
* Dynamic evaluation: Any other expression following a `$`
|
||||
|
||||
##### Lists
|
||||
Any two expressions joined by the Join operator (` ` [whitespace]), or a _variable reference_ referring to a list value
|
||||
* Syntactic Lists: Any _list_ enclosed in parentheses (`(` and `)`)
|
||||
|
||||
##### Comments
|
||||
Any text following a `#` in _bareword_ position, up to but not including a newline
|
||||
|
||||
##### Keywords
|
||||
The following tokens:
|
||||
* `for` in command name position
|
||||
* `in` as a syntactic element of a `for` expression
|
||||
|
||||
##### Special characters
|
||||
Any of the following:
|
||||
* `;` in bareword position
|
||||
* `\\n` (a newline) in _bareword_ position
|
||||
* Any of `(){}`
|
||||
* Any of `*?` not in _glob_ position
|
||||
|
||||
##### Tilde
|
||||
Any initial path segment starting with the character `~` in _bareword_ position, Optionally followed by a _bareword_ for the username
|
||||
|
||||
## Redirections
|
||||
The shell can create various redirections to file descriptors of a command before executing it, the general syntax for redirections is an optional file descriptor, followed by a redirection operator, followed by a destination.
|
||||
|
||||
There are four redirection operators corresponding to various file descriptor open modes: `Read`, `Write`, `WriteAppend` and `ReadWrite`, respectively `<`, `>`, `>>` and `<>`.
|
||||
|
||||
A special syntactic element `&fd` can reference a file descriptor as a destination.
|
||||
|
||||
Redirections take two main forms, Read/Write redirections, and fd closure redirections.
|
||||
##### Read/Write
|
||||
* Allowed operators: all
|
||||
* Allowed destinations: file paths (any shell _expression_) and _file descriptor references_
|
||||
|
||||
##### Close
|
||||
* Allowed operators: `Write` (`>`)
|
||||
* Allowed destinations: the special "close" reference `&-`
|
||||
|
||||
#### Examples
|
||||
```sh
|
||||
# Redirect the standard error to a file, and close the standard input
|
||||
$ 2> foo 1>&-
|
||||
|
||||
# Redirect a file as read-write into the standard input
|
||||
$ 1<>foo
|
||||
|
||||
# Redirect the standard output to /dev/null
|
||||
$ >/dev/null
|
||||
```
|
||||
|
||||
## Expansions
|
||||
The shell performs various expansions, in different stages.
|
||||
|
||||
* Glob Expansion: Globs shall be expanded to a list.
|
||||
|
||||
* Variable Expansion: Variables shall be expanded preserving their types.
|
||||
|
||||
* Juxtaposition Expansion: Juxtapositions shall be expanded as list products.
|
||||
|
||||
* Other expansions: Tildes, Evaluate expressions, etc. shall be expanded as needed.
|
||||
|
||||
### Juxtapositions
|
||||
Any two expressions joined without any operator are considered to be in a Juxtaposition, with the resulting value being the list product of two expressions.
|
||||
For instance, `(1 2)(3 4)` shall be evaluated to `(13 14 23 24)` by calculating the list product of the two expressions `(1 2)` and `(3 4)`.
|
||||
|
||||
### Tildes
|
||||
Any bareword starting with a tilde (`~`) and spanning up to the first path separator (`/`) - or EOL - is considered to be a tilde expansion with the text between the tilde and the separator being the _username_, which shall be expanded to a single string containing the home directory of the given _username_ (or the current user if no username is provided).
|
||||
|
||||
### Evaluate
|
||||
Evaluate expressions take the general form of a dollar sign (`$`) followed by some _expression_, which is evaluated by the rules below.
|
||||
- Should the _expression_ be a string, it shall be evaluated as a dynamic variable lookup by first evaluating the string, and then looking up the given variable.
|
||||
- Should the _expression_ be a list or a command, it shall be converted to a command, whose output (from the standard output) shall be captured, and split to a list with the shell local variable `IFS` (or the default splitter `\n` (newline, 0x0a)). It should be noted that the shell option `inline_exec_keep_empty_segments` will determine whether empty segments in the split list shall be preserved when this expression is evaluated, this behaviour is disabled by default.
|
||||
|
||||
## Commands
|
||||
|
||||
A `Command` is a single simple command, containing arguments and redirections for a single program. The shell can evaluate a sequence of commands, a conditional relation between commands, or various semantic elements composed of commands and intrinsics.
|
||||
|
||||
Commands can be either calls to Shell builtins, or external programs.
|
||||
|
||||
## Shell Semantic Elements
|
||||
The commands can be composed into semantic elements, producing composite commands:
|
||||
|
||||
### Sequences
|
||||
A sequence of commands, executed serially independent of each other: `Commanad ; Command ; Command ...`
|
||||
|
||||
It should be noted that a newline (`\\n`) can be substituted for the semicolon (`;`).
|
||||
|
||||
#### Example
|
||||
```sh
|
||||
# Do one thing, then do another
|
||||
echo foo; echo bar
|
||||
```
|
||||
|
||||
### Logical Relations
|
||||
A sequence of commands whose execution depends somehow on the result of another
|
||||
|
||||
##### `Command && Command && Command ...` (AND)
|
||||
Short-circuiting command evaluations, will cancel the entire chain should any command fails (have a non-zero exit code)
|
||||
|
||||
##### `Command || Command || Command ...` (OR)
|
||||
Short-circuiting command evaluation, will continue down the chain if any command fails.
|
||||
|
||||
It should be noted that `And` chains bind more tightly than `Or` chains, so an expression of the form `C1 && C2 || C3` is understood as "evaluate `C1`, if successful, evaluate `C2`, if not successful, evaluate `C3`".
|
||||
|
||||
#### Examples
|
||||
```sh
|
||||
# Create file if not found
|
||||
test -f foo.txt || touch foo.txt
|
||||
|
||||
# Announce execution status of a command
|
||||
rm test && echo "deleted!" || echo "failed with $?"
|
||||
```
|
||||
|
||||
#### Loops
|
||||
|
||||
##### For Loops
|
||||
For Loops evaluate a sequence of commands once per element in a given list.
|
||||
The shell has two forms of _for loops_, one with an explicitly named iteration variable, and one with an implicitly named one.
|
||||
The general syntax follows the form `for name in expr { sequence }`, and allows omitting the `name in` part to implicitly name the variable `it`.
|
||||
|
||||
A for-loop evaluates the _sequence_ once per every element in the _expr_, seetting the local variable _name_ to the element being processed.
|
||||
|
||||
The Shell shall cancel the for loop if two consecutive commands are interrupted via any of SIGINT (\^C), SIGQUIT (\^\\) or SIGKILL.
|
||||
|
||||
#### Examples
|
||||
```sh
|
||||
# Iterate over every non-hidden file in the current directory, and prepend '1-' to its name.
|
||||
$ for * { mv $it 1-$it }
|
||||
|
||||
# Iterate over a sequence and write each element to a file
|
||||
$ for i in $(seq 1 100) { echo $i >> foo }
|
||||
```
|
||||
|
||||
## Formal Grammar
|
||||
|
||||
### Shell Grammar
|
||||
```
|
||||
toplevel :: sequence?
|
||||
|
||||
sequence :: variable_decls? or_logical_sequence terminator sequence
|
||||
| variable_decls? or_logical_sequence '&' sequence
|
||||
| variable_decls? control_structure terminator sequence
|
||||
| variable_decls? or_logical_sequence
|
||||
| variable_decls? terminator sequence
|
||||
|
||||
or_logical_sequence :: and_logical_sequence '|' '|' and_logical_sequence
|
||||
| and_logical_sequence
|
||||
|
||||
and_logical_sequence :: pipe_sequence '&' '&' and_logical_sequence
|
||||
| pipe_sequence
|
||||
|
||||
terminator :: ';'
|
||||
| '\n'
|
||||
|
||||
variable_decls :: identifier '=' expression (' '+ variable_decls)? ' '*
|
||||
| identifier '=' '(' pipe_sequence ')' (' '+ variable_decls)? ' '*
|
||||
|
||||
pipe_sequence :: command '|' pipe_sequence
|
||||
| command
|
||||
|
||||
control_structure :: for_loop
|
||||
|
||||
for_loop :: 'for' ws+ (identifier ' '+ 'in' ws*)? expression ws+ '{' toplevel '}'
|
||||
|
||||
command :: redirection command
|
||||
| list_expression command?
|
||||
|
||||
redirection :: number? '>'{1,2} ' '* string_composite
|
||||
| number? '<' ' '* string_composite
|
||||
| number? '>' '&' number
|
||||
| number? '>' '&' '-'
|
||||
|
||||
list_expression :: ' '* expression (' '+ list_expression)?
|
||||
|
||||
expression :: evaluate expression?
|
||||
| string_composite expression?
|
||||
| comment expession?
|
||||
| '(' list_expression ')' expression?
|
||||
|
||||
evaluate :: '$' '(' pipe_sequence ')'
|
||||
| '$' expression {eval / dynamic resolve}
|
||||
|
||||
string_composite :: string string_composite?
|
||||
| variable string_composite?
|
||||
| bareword string_composite?
|
||||
| glob string_composite?
|
||||
|
||||
string :: '"' dquoted_string_inner '"'
|
||||
| "'" [^']* "'"
|
||||
|
||||
dquoted_string_inner :: '\' . dquoted_string_inner? {concat}
|
||||
| variable dquoted_string_inner? {compose}
|
||||
| . dquoted_string_inner?
|
||||
| '\' 'x' digit digit dquoted_string_inner?
|
||||
| '\' [abefrn] dquoted_string_inner?
|
||||
|
||||
variable :: '$' identifier
|
||||
| '$' '$'
|
||||
| '$' '?'
|
||||
| '$' '*'
|
||||
| '$' '#'
|
||||
| ...
|
||||
|
||||
comment :: '#' [^\n]*
|
||||
|
||||
bareword :: [^"'*$&#|()[\]{} ?;<>] bareword?
|
||||
| '\' [^"'*$&#|()[\]{} ?;<>] bareword?
|
||||
|
||||
bareword_with_tilde_expansion :: '~' bareword?
|
||||
|
||||
glob :: [*?] bareword?
|
||||
| bareword [*?]
|
||||
|
||||
digit :: <native hex digit>
|
||||
number :: <number in base 10>
|
||||
identifier :: <string of word characters>
|
||||
```
|
|
@ -125,7 +125,9 @@ variable_decls :: identifier '=' expression (' '+ variable_decls)? ' '*
|
|||
pipe_sequence :: command '|' pipe_sequence
|
||||
| command
|
||||
|
||||
control_structure :: 'for' ws+ (identifier ' '+ 'in' ws*)? expression ws+ '{' toplevel '}'
|
||||
control_structure :: for_loop
|
||||
|
||||
for_loop :: 'for' ws+ (identifier ' '+ 'in' ws*)? expression ws+ '{' toplevel '}'
|
||||
|
||||
command :: redirection command
|
||||
| list_expression command?
|
||||
|
|
Loading…
Add table
Reference in a new issue