Why Sponsor Oils? | source | all docs for version 0.24.0 | all versions | oilshell.org
Only a few things break when you put this at the top of a shell script:
shopt --set ysh:upgrade
This doc enumerates and explains them.
First, let's emphasize the good things that happen when you upgrade:
if (x > 0)
instead of if [ "$x" -gt 0 ]
.cd /tmp { echo $PWD }
$var
instead
of "$var"
, and splice arrays with @myarray
.You can also use bin/osh
indefinitely, in which case you don't need to read
this doc. OSH is a highly compatible Unix shell.
Now onto the breakages. Most of them are unlikely, but worth noting.
if ( )
and while ( )
take expressions, not subshell commandsCode like if ( ls /tmp )
is valid shell, but it's almost always a misuse of
the language. Parentheses mean subshell, not grouping as in C or Python.
In YSH:
if (x > 0)
for true/false expressionsforkwait
builtin for subshells, which are uncommon. (It's like
invoking the fork
builtin, then the wait
builtin.)No:
( cd /tmp; rm *.sh )
Yes:
forkwait {
cd /tmp
rm *.sh
}
Better:
cd /tmp { # no process created
rm *.sh
}
echo $PWD # restored
(Option parse_paren
is part of group ysh:upgrade
.)
@()
is spliced command sub, not extended globYSH doesn't have implicit word splitting, so we want @(seq 3)
to be
consistent with $(hostname)
. They're related in the same way that @myarray
and $mystr
are.
This means that @()
is no longer extended glob, and ,()
is an alias.
No:
echo @(*.cc|*.h)
Use this YSH alias instead:
echo ,(*.cc|*.h)
(Option parse_at
is part of group ysh:upgrade
.)
r'c:\Users\'
is a raw string, not joined stringsThe meaning of \
within string literals can be confusing, so YSH
distinguishes them like this:
$'foo\n'
$
prefix means that C-style backslash escapes are respected.r'c:\Users\'
r
prefix means the backslashes are literal.'c:\Users\'
. YSH accepts this in command mode
for compatibility, but not expression mode.The prefix changes the meaning of commands like:
echo r'foo'
# => foo in YSH
# => rfoo in shell, because of implicit joining
Instead, write 'rfoo'
if that's what you mean.
(Option parse_raw_string
is part of group ysh:upgrade
.)
[
In a command, the [
character starts a lazy arg list:
assert [42 === x]
In shell, [
is part of the glob syntax:
echo [ch] # extremely rare pattern matching c or h
This is more common, and still works:
echo *.[ch]
You can still express the former by explicitly invoking glob('[ch]')
.
(Option parse_bracket
is part of group ysh:upgrade
.)
Like regular globs, the extended glob syntax is used in two ways:
case
[[ x == !(*.cc|*.h) ]]
cp !(*.cc|*.h) /tmp
local -a myarray=( !(*.cc|*.h) )
for
loopsExtended globs are not supported in Simple Word Evaluation, so you can't use them in the second way after upgrading.
You may want to use the find
command or Egg expressions
instead.
(Option simple_word_eval
is part of group ysh:upgrade
.)
ysh:upgrade
OptionsOption parse_at
. In YSH, @
is used to splice arrays. To pass a string
@foo
to a command, quote it like '@foo'
.
Option parse_brace
. Braces after commands start block arguments. To change
to a directory named {
, quote it like cd '{'
.
Option parse_equals
. A statement like x = 42
is a "bare assignment" or
attribute. To pass =
to a command x
, quote it like x '='
.
=
operator, a word like =x
can't be the first word in a command.
To invoke such commands, quote them like '=x'
.proc
, const
, var
, and setvar
. To use them
as command names, quote them like 'proc'
.There is very little reason to use commands like '=x'
and 'proc'
, so you
will likely never run into this!
This concludes the list of features that's broken when you upgrade from OSH to YSH. We tried to keep this list as small as possible.
There are other features that are discouraged, like $(( x + 1 ))
, (( i++ ))
, [[ $s =~ $pat ]]
, and ${s%%prefix}
. These have better alternatives in
the YSH expression language, but they can still be used. See YSH vs. Shell
Idioms.
Also related: Known Differences Between OSH and Other Shells.
Here are some notable non-breaking changes.
Procs have truly local variables like Python and JavaScript. There's no dynamic scope rule, as with shell functions.
This is something to be aware of, but isn't technically a breakage because shell functions still work the same way in YSH.
In YSH, env vars live in the ENV dict. So instead of $EDITOR
, you should
use $[ENV.EDITOR]
.
But doesn't break when you shopt --set ysh:upgrade
, only when you use
bin/ysh
.
Thank you to ca2013
for reviewing this doc.