| 1 | ---
|
| 2 | ---
|
| 3 |
|
| 4 | YSH vs. Shell
|
| 5 | =============
|
| 6 |
|
| 7 | This doc may help shell users understand YSH. If you don't want to read a
|
| 8 | comparison, see [A Tour of YSH](ysh-tour.html).
|
| 9 |
|
| 10 | <div id="toc">
|
| 11 | </div>
|
| 12 |
|
| 13 | ## YSH is Stricter at Parse Time, and Runtime
|
| 14 |
|
| 15 | OSH and YSH both prefer [static
|
| 16 | parsing](https://www.oilshell.org/blog/2016/10/22.html), so you get syntax
|
| 17 | errors up front. In shell, syntax errors can occur at runtime.
|
| 18 |
|
| 19 | At runtime, we have `strict_*` shell options that handle edge cases. YSH
|
| 20 | generally fails faster than shell. They're in the [option group](options.html)
|
| 21 | `strict:all`.
|
| 22 |
|
| 23 | ## Three Core Sublanguages, Instead of 4
|
| 24 |
|
| 25 | - Sublanguages in Bash: Command, Word, Arith, Bool
|
| 26 | - Sublanguages in YSH: Command, Word, **Expression**
|
| 27 |
|
| 28 | See the [List of
|
| 29 | Sublanguages](https://www.oilshell.org/blog/2019/02/07.html#list-of-sublanguages)
|
| 30 | on the blog.
|
| 31 |
|
| 32 | ### Python-like Expressions Replace Arith and Bool
|
| 33 |
|
| 34 | This means that all these constructs are discouraged in favor of YSH
|
| 35 | expressions:
|
| 36 |
|
| 37 | ```
|
| 38 | [[ $x =~ $pat ]]
|
| 39 |
|
| 40 | x=$(( x + 1 ))
|
| 41 | (( x = x + 1 ))
|
| 42 | let x=x+1
|
| 43 |
|
| 44 | declare -A assoc=(['k1']=v1 ['k2']=v2)
|
| 45 | ```
|
| 46 |
|
| 47 | See [YSH vs. Shell Idioms](idioms.html) for more rewrites.
|
| 48 |
|
| 49 | ### Command Sublanguage
|
| 50 |
|
| 51 | Notable differences:
|
| 52 |
|
| 53 | **Curly Braces** `{ }`, instead of `then fi` and `do done`.
|
| 54 |
|
| 55 | **Keywords for Variable Assignment** like `var`, `const`, `setvar`, instead of
|
| 56 | builtins like `local`, `readonly`, `myvar=foo`, etc.
|
| 57 |
|
| 58 | Array literals like `var a = :| ale bean |` instead of `local a=(ale bean)`
|
| 59 |
|
| 60 | **[Procs, Funcs, and Blocks](proc-func.html)** for modularity:
|
| 61 |
|
| 62 | - Shell functions are "upgraded" into procs, with typed and named parameters.
|
| 63 | - Procs have truly local variables, like Python and JavaScript. There's no
|
| 64 | [dynamic scope]($xref:dynamic-scope) rule, as with shell functions.
|
| 65 | - Python-like pure funcs compute on "interior" data.
|
| 66 | - Ruby-like blocks enable reflection and metaprogramming.
|
| 67 | - Including declarative [Hay](hay.html) blocks
|
| 68 |
|
| 69 | **Multiline strings** replace here docs.
|
| 70 |
|
| 71 | `fork` and `forkwait` **builtins**, instead of `&` and `()`
|
| 72 |
|
| 73 | Parentheses are instead used for Python-like expressions, e.g.
|
| 74 |
|
| 75 | if (x > 0) {
|
| 76 | echo 'positive'
|
| 77 | }
|
| 78 |
|
| 79 | ### Word Sublanguage
|
| 80 |
|
| 81 | Notable differences:
|
| 82 |
|
| 83 | [Simple Word Evaluation](simple-word-eval.html) replaces implicit word
|
| 84 | splitting, and dynamic parsing/evaluation of globs. It adds splicing of Lists
|
| 85 | into `argv` arrays.
|
| 86 |
|
| 87 | **Expression substitution** like `echo $[42 + a[i]]`.
|
| 88 |
|
| 89 | This includes function calls: `echo $[join(['pea', nut'])]`
|
| 90 |
|
| 91 | Raw strings can have an `r` prefix, like `echo r'C:\Program Files\'`.
|
| 92 |
|
| 93 | ## Runtime
|
| 94 |
|
| 95 | ### Builtin Commands and Functions
|
| 96 |
|
| 97 | - YSH adds long flags to builtin commands, like `read --all`.
|
| 98 | - YSH has builtin functions like `join()`.
|
| 99 |
|
| 100 | ### Shell Options, `shvar`, Registers
|
| 101 |
|
| 102 | We upgrade bash's `shopt` mechanism with more options, like `shopt --set
|
| 103 | parse_brace`. These global options are controlled with scope
|
| 104 |
|
| 105 | shopt --unset errexit {
|
| 106 | rm /tmp/*
|
| 107 | rm /etc/*
|
| 108 | }
|
| 109 |
|
| 110 | A `shvar` is similar to a `shopt`, but it has a string value, like `$IFS` and
|
| 111 | `$PATH`.
|
| 112 |
|
| 113 | shvar PATH=. {
|
| 114 | my-command /tmp
|
| 115 | }
|
| 116 |
|
| 117 | **Registers** are special variables set by the interpreter, beginning with `_`:
|
| 118 |
|
| 119 | - `try` sets `_error` (`_error.code` preferred over `$?`)
|
| 120 | - `_pipeline_status`, `_group()`, etc.
|
| 121 |
|
| 122 | <!--
|
| 123 | ## TODO
|
| 124 |
|
| 125 | - String Safety: tagged strings, ${x|html}
|
| 126 | - maybe captureBuffer(^(echo hi))
|
| 127 | - [Modules](modules.html): for organizing code into files. 'use'
|
| 128 |
|
| 129 | -->
|
| 130 |
|
| 131 | ### Data Languages, Not Ad Hoc Parsing
|
| 132 |
|
| 133 | YSH programs are encouraged to use our JSON-like data languages to serialize
|
| 134 | data.
|
| 135 |
|
| 136 | For example, using an encoded array like `["one\n", "two \t three"]` results in
|
| 137 | more obviously correct code than using ad hoc delimiters like spaces, commas,
|
| 138 | or colons.
|
| 139 |
|
| 140 | ## Shell Features Retained
|
| 141 |
|
| 142 | These bash features are still idiomatic in YSH:
|
| 143 |
|
| 144 | - Brace expansion like `{alice,bob}@example.com`
|
| 145 | - Process Substitution like `diff <(sort left.txt) <(sort right.txt)`
|
| 146 |
|
| 147 | ## Related Links
|
| 148 |
|
| 149 | - [YSH vs. Shell Idioms](idioms.html) shows example of YSH and shell side by
|
| 150 | side.
|
| 151 | - [What Breaks When You Upgrade to YSH](upgrade-breakage.html). These are
|
| 152 | breaking changes.
|
| 153 | - [YSH Expressions vs. Python](ysh-vs-python.html)
|