OILS / ysh / testdata / tour.ysh View on Github | oilshell.org

241 lines, 78 significant
1# Command language
2
3## Simple commands
4
5### variable declaration and mutation
6
7# Declaring a variable does NOT looks like this:
8# Variable="Some string" => name=val isn't allowed when shopt 'parse_equals' is on.
9# Hint: add 'env' before it, or spaces around =
10
11# Nor like this
12# Variable = "Some string" # => same error
13
14# this is the preferred way
15# no need for capitalization like in bash
16var variable = "Some string"
17
18# also valid but not idomatic
19set variable = "Another string"
20
21# const to declare a constant
22const immutable = "definitive"
23
24# this will not work
25# set immutable = "not so sure" => Can't modify constant 'immutable'
26
27# mutate a variable with setvar
28var new = "a brave new world"
29setvar new = "perhaps it's already here"
30echo $new
31
32# setglobal will create or mutate a global variable
33setglobal the_answer = 42
34echo $the_answer
35
36# there are more ways to set variable by passing them
37# to procs. This will be expanded in the procs section
38
39### Variable substitution
40
41var regular_string = "I am just a normal string"
42echo $regular_string # quotes not needed
43#### if you want to do string interpolation
44echo "$regular_string and $regular_string"
45#### you need to do it another way if you want to substitute before a _
46# this will not work "$regular_string_"
47# as it will look for the regular_string_ variable
48echo "${regular_string}_" # but this will
49
50### Parameter expansion works just like in bash
51var some_string = "I am some string"
52echo ${some_string/another/some} # => I am another string
53
54### Strings
55
56# this will not work
57# echo "\n" => Invalid char escape in double quoted string
58# this prints the characters
59echo '\n'
60# use $ to print a new line
61echo $'\n'
62
63# unicode works like this
64# var unicode = j"mu = \u{3bc}"
65# echo $unicode
66
67# but not like this
68# var unicode = 'mu = \u{3bc}' => Strings with backslashes should look like r'\n', c'\n' or $'\n'
69
70### builtins
71
72#### echo
73# takes at most 1 argument and prints to stdout
74echo "Hello world!" # => Hello world!
75
76#### write
77# write outputs to stdout
78# write has a -- separator to not confuse command line arguments and what you want to print
79var i_am_a_string = "I'm just a string"
80write -- $i_am_a_string
81# if you have a string with a newline in it
82var i_have_a_newline = $'it\'s true I really do \n'
83# write works well with it, unlike bash's printf
84write -- $i_have_a_newline
85# you can print the content without the newline with -n
86write -n -- $i_have_a_newline
87
88#### test
89# test has been improved to be a little less crytic
90
91# test if something is a directory
92test --dir /tmp || echo "Not a dir"
93test -d /tmp # still works but less readable
94
95# test if something is a file
96test --file /tmp/maybe_a_file || echo "Not a file"
97
98### Procs
99
100### think of procs as a better version of bash's functions
101### use proc for abstraction
102proc abstract() {
103 echo "I'm an abstraction"
104}
105
106### and call it without brackets
107abstract
108
109### proc can't access variables they are not given as params
110### proc print_variable() {
111### echo $some_not_given_variable
112### }
113### print_variable
114### fatal: Undefined variable 'some_not_given_variable'
115
116proc print_variable(passed_variable) {
117 echo $passed_variable
118}
119
120### call procs with arguments without brackets
121var variable_to_pass = "I'm passed"
122print_variable $variable_to_pass
123
124# If you're going to use a shell function or proc in a condition, wrap it with 'try'
125# to avoid a strict_errexit error
126proc myproc {
127 echo hi
128 return 1
129}
130
131try {
132 myproc
133}
134if (_status !== 0) {
135 echo failure
136}
137
138### external commands
139
140### Ruby like blocks
141
142## Redirects
143
144## Pipelines
145
146## Control flow
147
148### general
149
150### use command substitution to assign the result of a command to a variable
151var year = $(date -u +"%Y")
152echo $year
153
154# a failure will exit immediately
155# var year = $(date --wrong-flag +"%Y") => date: illegal option -- -
156# usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
157# [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
158# var year = $(date --wrong-flag "%Y")
159# ^~
160# ./tour.sh:38: fatal: Command sub exited with status 1 (command.Simple)
161
162
163### if
164
165# if works just like you would expect
166
167if true {
168 echo "Here I am!"
169} else {
170 echo "I'll never be"
171}
172
173# However be careful, brackets have a special meaning
174# those are for conditionals, you won't be able to
175# run functions inside those
176proc is_it_true() {
177 false
178}
179# this won't work
180# if (! is_it_true) {
181# echo "could be anything really"
182# }
183# Syntax error in expression (near Id.Expr_Bang)
184# to make it work you have to 'try' the proc
185# and remove the brackets
186
187try { is_it_true }
188if (_status !== 0) {
189 echo "could be anything really"
190}
191
192# an error in a proc will print
193proc err_today() {
194 date --wrong-flag
195}
196
197try {
198 err_today
199 echo "will never be executed"
200}
201if (_status !== 0) {
202 # this will also print the proc error
203 # date: illegal option -- -
204 # usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
205 # [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
206 echo "there was an error"
207}
208
209### case
210
211### for
212
213### while
214
215## fork and wait
216
217## Expression language
218
219### Eggex
220
221#### matching happens with eggexes, which are a different take on regex
222#### you can use
223#### digit => to match numbers
224#### word => to match any character that is not a space
225#### space => to match all the non word characters (tab, newline...)
226#### dot => to match any character
227
228var s = '123'
229if (s ~ /digit+/) {
230 echo 'number'
231}
232
233#### extract a submatch with < >
234#### if ($(date -u +"%Y-%m-%d") ~ /< digit{4} :year> '-' <digit{2} :month>!word<digit{2} :day>/) {
235if ($(date -u +"%Y-%m-%d") ~ /<capture digit{4} as year> '-' <capture digit{2} as month> '-' <capture digit{2} as day>/) {
236 # extract a match by number
237 const complete_match = _match(0)
238 const group_match = _match(1)
239 echo $complete_match
240 echo $group_match
241}