source | all docs for version 0.8.1 | all versions | oilshell.org
Warning: Work in progress! Leave feedback on Zulip or Github if you'd like this doc to be updated.
These informal notes may help you understand Oil.
Oil's design is more conservative than that of other alternative shells. It
The command and word syntax comes from shell:
ls | wc -l # pipeline
echo $var "${var} $(hostname)" # variable and command sub
echo one; echo two # sequence of commands
test -d /tmp && test -d /tmp/foo
Oil's own shell-like extensions:
echo $[1 + 2*3] # Expression substitution
echo $strfunc(x, y) # Inline Function Calls
We implement many bash semantics, like "named references" for out variables:
f() {
local -n out=$1 # -n for named reference
out=bar
}
myvar=foo
f myvar
echo $myvar # prints "bar"
But clean up the syntax:
proc f(:out) { # "out param" declared with :
setref out = 1
}
var myvar = 'foo'
f :myvar # caller prefixes the var name with :
echo $myvar # prints "bar"
Historical note: Usenix 93. korn shell was used for GUIs and such!
Oil's expression language is mostly Python compatible. Expressions occur on
the RHS of =
:
var a = 1 + a[i]
var b = fib(10)
var c = 'yes' if mybool else r'no'
Proc signatures resemble Python:
proc cp(src, dest='/tmp') { # Python-like default value
cp --verbose $src $dest
}
Differences:
a + b
is for addition, whle a ++ b
is for concatenation.a < b
is only for numbers. cmp()
could be for strings.+=
in
for array/list membership. Only dict membership.s[i]
returns an integer "rune", not a string?42,
are disallowed, in favor of the more explicit
tup(42)
.Oil uses JavaScript's dict literals:
# Unquoted keys. Sigil to avoid confusion with blocks.
d = {name: 'Bob', age: 10}
d = {[mystr]: 'value'} # key expressions in []
And "structured programming" looks like C / Java / JavaScript:
if (x > 0) {
echo 'positive'
} else {
echo '0 or negative'
}
var x = 5
while (x > 0) {
echo $x
setvar x -= 1
}
Oil has Ruby-like blocks:
cd /tmp {
echo $PWD # prints /tmp
}
echo $PWD
proc foo (&block) { run(block) }
var myblock = &(echo $PWD)
(Julia has something like blocks too.)
And the syntax for references to variable names:
read :line # populate $line variable
push :myarray one two three # append to array
The @
character (which PowerShell also uses) comes from Perl:
var myarray = %(one two three)
echo @myarray # @ is the "splice" operator
echo @arrayfunc(x, y)
for i in @(seq 3) { # split command sub
echo $i
}
Perl can be viewed as a mixture of shell, awk, and sed. Oil is a similar agglomeration of related languages.
The builtin flags syntax comes from Go:
mybuiltin --show=0 # turn a flag that's default true
It also uses a native UTF-8 representation of strings.
Oil gets its regex match operator from Awk:
if (mystr ~ /digit+/) {
echo 'Number'
}
(We don't use Perl's =~
operator.)
TODO
Features influenced by these languages are planned, but not implemented.
Oil uses proc
and set
, which makes it look something like Tcl:
proc p(x) {
set y = x * 2
echo $y
}
p 3 # prints 6
But Oil isn't homoiconic like Tcl is. It avoids dynamic parsing, and has a lot of syntax.
So this is superficial, an instance of "convergent evolution".
However, Data Definition and Code Generation in Tcl (PDF) shows how Tcl can be used a configuration language:
change 6/11/2003 {
author "Will Duquette"
description {
Added the SATl component to UCLO.
}
}
Oil's blocks (also inspired Ruby) would allow this to be expressed very similarly:
change 6/11/2003 {
author = "Will Duquette"
description = '''
Added the SATl component to UCLO.
'''
}
(This mechanism is still in progress.)
Oil also uses a leading =
to print expressions in the REPL.
= 1 + 2
PHP has global variables like _REQUEST
and _POST
.
Oil may have _argv
, _match()
, _start()
, etc. These are global variables
that are "silently" mutated by the interpreter, and functions to access such
global data.
Shell is already mix of:
Oil is:
${x%%a}
${x//}
getting rid of all this crap. Just use functions.