OILS / doc / ref / chap-mini-lang.md View on Github | oils.pub

256 lines, 165 significant
1---
2title: Mini Languages (Oils Reference)
3all_docs_url: ..
4body_css_class: width40
5default_highlighter: oils-sh
6preserve_anchor_case: yes
7---
8
9<div class="doc-ref-header">
10
11[Oils Reference](index.html) &mdash;
12Chapter **Mini Languages**
13
14</div>
15
16This chapter describes "mini-languages" like glob patterns and brace expansion.
17
18In contrast, the main sub languages of YSH are [command](chap-cmd-lang.html),
19[word](chap-word-lang.html), and [expression](chap-expr-lang.html).
20
21<span class="in-progress">(in progress)</span>
22
23<div id="dense-toc">
24</div>
25
26<h2 id="sublang">Other Shell Sublanguages</h2>
27
28## Arithmetic
29
30### arith-context
31
32Arithmetic expressions are parsed and evaluated in many parts of POSIX shell
33and bash.
34
35Static:
36
37 a=$(( x + 1 )) # POSIX shell
38
39 # bash
40 (( a = x + 1 ))
41
42 for (( i = 0; i < n; ++i )); do
43 echo $i
44 done
45
46Dynamic:
47
48 [[ 5 -eq 3+x ]] # but not test 5 -eq 3+x
49
50Array index contexts:
51
52 echo ${a[i+1]} # get
53 echo ${#a[i+1]} # calculate
54
55 a[i+1]=foo # set
56
57 printf -v 'a[i+1]' # assign to this location
58 unset 'a[i+1]' # unset location
59
60 echo ${a[@] : i+1 : i+2 } # bash slicing
61
62bash allows similar array expressions with `test -v`:
63
64 test -v 'array[i+1]' # is array item set?
65 test -v 'assoc[$myvar]' # is assoc array key set?
66
67 [[ -v 'array[i+1]' ]] # ditto
68 [[ -v 'assoc[$myvar]' ]]
69
70But OSH allows only integers and "bare" string constants:
71
72 test -v 'array[42]' # is array item set?
73 test -v 'assoc[key]' # is assoc array key set?
74
75### sh-numbers
76
77### sh-arith
78
79### sh-logical
80
81### sh-bitwise
82
83## Boolean
84
85### bool-expr
86
87Boolean expressions can be use the `test` builtin:
88
89 test ! $x -a $y -o $z
90
91Or the `[[` command language:
92
93 [[ ! $x && $y || $z ]]
94
95### bool-infix
96
97Examples:
98
99 test $a -nt $b
100 test $x == $y
101
102### bool-path
103
104Example:
105
106 test -d /etc
107 test -e /
108 test -f myfile
109
110YSH has long flags:
111
112 test --dir /etc
113 test --exists /
114 test --file myfile
115
116### bool-str
117
118 test -n foo # => status 0 / true -- foo is non-empty
119 test -z '' # => status 0 / true -- '' is empty / zero-length
120
121### bool-other
122
123Test if a shell option is set:
124
125 test -o errexit
126
127Test the values of variables:
128
129 test -v var_name # is variable defined?
130 test -v name[index] # is an entry in a container set?
131
132Notes:
133
134- In `name[index]`, OSH doesn't allow arithmetic expressions / dynamic parsing,
135 as bash does.
136- `shopt --set strict_word_eval` exposes "syntax errors" in `name[index]`, and
137 is recommended.
138 - Without this option, `test -v` will silently return `1` (false) when given
139 nonsense input, like `test -v /`.
140
141## Patterns
142
143### glob-pat
144
145Glob patterns look like:
146
147 echo *.py # Ends with .py
148 echo *.[ch] # Ends with .c or .h
149
150This syntax is used in:
151
152- "Array of words" contexts ([osh-glob][], [ysh-glob][])
153 - [simple-command][] - like `echo *.py`
154 - bash arrays `a=( *.py )`
155 - YSH arrays `var a = :| *.py |`
156 - for loops `for x in *.py; do ...`
157- [case][] patterns
158- [dbracket][] matching - `[[ x == *.py ]]`
159- Word operations
160 - [op-strip][] - `${x#*.py}`
161 - [op-patsub][] - `${x//*.py/replace}` -
162
163[osh-glob]: chap-word-lang.html#osh-glob
164[ysh-glob]: chap-word-lang.html#ysh-glob
165
166[simple-command]: chap-cmd-lang.html#simple-command
167[case]: chap-cmd-lang.html#case
168[dbracket]: chap-cmd-lang.html#dbracket
169
170[op-strip]: chap-word-lang.html#op-strip
171[op-patsub]: chap-word-lang.html#op-patsub
172
173### extglob
174
175Extended globs let you use logical operations with globs.
176
177They may be **slow**. Regexes and eggexes are preferred.
178
179 echo @(*.cc|*.h) # Show files ending with .cc or .h
180 echo !(*.cc|*.h) # Show every file that does NOT end with .cc or .h
181
182Extended globs can appear in most of the places globs can, except
183[op-patsub][] (because we implement it by translating.
184
185### regex
186
187POSIX ERE (extended regular expressions) are part of bash's [dbracket][]:
188
189 x=123
190 if [[ x =~ '[0-9]+ ]]; then
191 echo 'looks like a number'
192 fi
193
194## Other Sublang
195
196### braces
197
198Brace expansion saves you typing:
199
200 $ echo {foo,bar}@example.com
201 foo@example.com bar@example.com
202
203You can use it with number ranges:
204
205 $ echo foo{1..3}
206 foo1 foo2 foo3
207
208(The numbers must be **constant**.)
209
210Technically, it does a cartesian product, which is 3 X 2 in this case:
211
212 $ for x in foo{1..3}-{X,Y}; do echo $x; done
213 foo1-X
214 foo1-Y
215 foo2-X
216 foo2-Y
217 foo3-X
218 foo3-Y
219
220### histsub
221
222History substitution uses `!`.
223
224### char-escapes
225
226These backslash escape sequences are used in [echo
227-e](chap-builtin-cmd.html#echo), [printf](chap-builtin-cmd.html#printf), and in
228C-style strings like `$'foo\n'`:
229
230 \\ backslash
231 \a alert (BEL)
232 \b backspace
233 \c stop processing remaining input
234 \e the escape character \x1b
235 \f form feed
236 \n newline
237 \r carriage return
238 \t tab
239 \v vertical tab
240 \xHH the byte with value HH, in hexadecimal
241 \uHHHH the unicode char with value HHHH, in hexadecimal
242 \UHHHHHHHH the unicode char with value HHHHHHHH, in hexadecimal
243
244Also:
245
246 \" Double quote.
247
248Inconsistent octal escapes:
249
250 \0NNN echo -e '\0123'
251 \NNN printf '\123'
252 echo $'\123'
253
254TODO: Verify other differences between `echo -e`, `printf`, and `$''`. See
255`frontend/lexer_def.py`.
256