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)
|