source | all docs for version 0.9.2 | all versions | oilshell.org
Warning: Work in progress! Leave feedback on Zulip or Github if you'd like this doc to be updated.
This document describes global shell options, which look like this:
shopt --set strict_backslash # Oil style
set -o errexit # Bourne shell style
They can affect parsing or execution, and are used to gradually turn the OSH language into the Oil language.
For example, Oil doesn't have word splitting on whitespace, use Simple Word Evaluation by default. (Blog: Oil Doesn't Require Quoting Everywhere).
This isn't the only use for them, but it's one of the main uses.
The option groups strict:all
and oil:basic
are "canned settings" that
relieve you of having to know about dozens of shell options.
If you put this line at the top of your shell script, it will still run under other shells, but OSH will act as sort of a "runtime linter":
# Abort on more errors, but fixes will still be compatible
shopt -s strict:all 2>/dev/null || true
If you don't care about running under other shells, use this:
# Start enabling Oil syntax and semantics
shopt --set oil:basic
This second line may break a few things, but is designed to be an easy upgrade. See Shell Language Deprecations.
Use bin/oil
for a brand new Oil script, opting into all enhancements.
Your shebang line might be #!/usr/bin/env oil
. This is the equivalent of
shopt --set oil:all
.
That's all most users need to know. For more details, see the wiki page: Gradually Upgrading Shell to Oil.
There are several different ways of using shell options.
Oil has long flags for readability, which are preferred:
shopt --set errexit
shopt --unset errexit
It also allows scoped options:
shopt --unset errexit {
false # non-zero status ignored
ls /bad
}
false # original setting restored
For compatibility, these styles works in Oil:
set -e # abort script on non-zero exit exit code
set +e # turn it off
set -o errexit # a more readable version of the above
set +o errexit
Bash-style option with shopt
:
shopt -s nullglob # turn it on
shopt -u nullglob # turn it off
You typically invoke the shopt
builtin at the the top of a script, but you
can also set options at the command line:
osh -O errexit -c 'shopt -p -o' # turn on Bourne option
osh +O errexit -c 'shopt -p -o' # turn off Bourne option
osh -O strict_tilde -c 'shopt -p' # turn on Oil option
osh +O strict_tilde -c 'shopt -p' # turn off Oil option
Shell has many ways to do this, like:
set -o # print all Bourne shell options
shopt -p # print all bash options
shopt -p nullglob failglob # print selected options
TODO: Oil should enable shopt --print
for all options. It should have a flat
list.
To let you turn them all on or off at once.
strict:all
: Help you find bugs. Do NOT break things to improve style.oil:basic
: Allow using Oil features that are unlikely to break something,
or have an easy fix (example: @foo
-> '@foo'
, and ()
-> forkwait
).
Again, do NOT break things to improve style.oil:all
: Allow even more Oil features. And also break things to improve
style. (Example: simple_eval_builtin
).TODO: Do we need simple:all
?
oil:all
Runnig bin/oil
is equivalent to
shopt --set oil:all
It turns on:
errexit
, nounset
(sh
modes to get more errors)pipefail
and inherit_errexit
(bash
modes to get more errors)simple_word_eval
(subsumes nullglob
that strict:all
includes)command_sub_errexit
strict_*
(strict_array
, etc.)parse_*
(parse_at
, etc.)This is NOT FORMAL like GROUPS. GROUPS AND Kinds are different!
They are orthogonal axes.
parse_*
: Change parsing.
parse_at
, parse_equals
.parse_backticks
, parse_backslash
,
parse_dollar
.strict_*
: Fail at runtime instead of ignoring the bug like bash.
${#s}
on invalid unicode is a runtime error.~typo
is a runtime error.simple_*
: Break things to improve style.
simple_eval_builtin
, simple_echo
.simple_word_eval
is the most aggresiveThese options produce more programming errors. Importantly, the resulting program is still compatible with other shells.
For example, shopt -s strict_array
produces runtime errors when you confuse
strings and arrays. After you fix these problems, your program will still run
correctly under bash
.
In contrast, if you set shopt -s simple_word_eval
(an option that doesn't
start with strict_
), the semantics of your program have changed, and you can
no longer run it under other shells. It's considered an "Oil option": by
setting it, you're using parts of the Oil language.
Options that affect parsing start with parse_
. For example, shopt -s parse_at
enables splicing with the @
character:
var words = %(ale bean)
write -- @words
# =>
# ale
# bean
and inline function calls:
write -- @split('ale bean')
# =>
# ale
# bean
As another example, shopt --set parse_brace
takes over the { }
characters.
Specifically, it does three things:
cd
to take a block (discussed in a Zulip
thread)if
, case
, for
, and while/until
, use curly brace
delimiters instead of then/fi
, do/done
, etc. See below.foo{
is
an error. It has to be echo foo\{
or echo 'foo{'
.
{pea,coco}nut
Here's idiomatic Oil syntax after parse_brace
:
cd /tmp {
echo $PWD
}
if test -d foo {
echo 'dir'
} elif test -f foo {
echo 'file'
} else {
echo 'neither'
}
# Single line statements are supported:
if test -d / { echo 'dir' } else { echo 'nope' }
while true {
echo hi
break
}
# Loop over words
for x in ale bean *.sh {
echo $x
}
# Replace 'in' with {, and 'esac' with }
case $x {
*.py)
echo python
;;
*.sh)
echo shell
;;
}
What's the motivation for this? Mainly familiarity: I hear a lot of feedback that nobody can remember how to write if statements in shell. See The Simplest Explanation of Oil.
simple_echo
. Changes the flags accepted by the echo
builtin, and style of flag parsing.
See the Builtins > echo
below.simple_word_eval
. Word evaluation consists of one stage rather than three:
TODO: copy examples from spec tests
echo $dir/*.py
command_sub_errexit
. A error in a command sub can cause the parent
shell to exit fatally. Also see inherit_errexit
and strict_errexit
.These documents have a short description of each option:
(TODO: longer descriptions.)