Why Sponsor Oils? | source | all docs for version 0.20.0 | all versions | oilshell.org
Here are some common questions about YSH. Many of the answers boil down to the fact that YSH is a smooth upgrade from bash.
Old and new constructs exist side-by-side. New constructs have fewer "gotchas".
myvar, $myvar, and "$myvar" ?YSH is more like Python/JavaScript rather than PHP/Perl, so it doesn't use the
$ sigil as much.
Never use $ on the left-hand side:
var mystr = "foo" # not var $mystr
Use $ to substitute vars into commands:
echo $mystr
echo $mystr/subdir # no quotes in commands
or quoted strings:
echo "$mystr/subdir"
var x = "$mystr/subdir"
Rarely use $ on the right-hand side:
var x = mystr # preferred
var x = $mystr # ILLEGAL -- use remove $
var x = ${mystr:-} # occasionally useful
var x = $? # allowed
See Command vs. Expression Mode for more details.
~/src or ~bob/git in a YSH assignment?This should cover 80% of cases:
var path = "$HOME/src" # equivalent to ~/src
The old shell style will cover the remaining cases:
declare path=~/src
readonly other=~bob/git
This is only in issue in expressions. The traditional shell idioms work in command mode:
echo ~/src ~bob/git
# => /home/alice/src /home/bob/git
The underlying design issue is that the YSH expression ~bob looks like a
unary operator and a variable, not some kind of string substitution.
Also, quoted "~" is a literal tilde, and shells disagree on what ~"" means.
The rules are subtle, so we avoid inventing new ones.
echo -e or echo -n?YSH removed these flags to echo because it has good alternatives
To escape variables, use the statically-parsed string language, rather than
echo -e:
echo $'tab \t newline \n' # YES
echo j"tab \t newline \n" # TODO: J8 notation
echo -e tab \t newline \n' # NO
To omit the newline, use the write builtin, rather than echo -n:
write -n 'prefix' # YES
write --end '' -- 'prefix' # synonym
echo -n 'prefix' # NO
-e and -n Removed?Shell's echo is the only builtin that doesn't accept -- to stop flag
processing.
This means that echo "$flag" always has a few bugs: when flag is -e,
-n, -en, or -ne. There's no way to fix this bug in POSIX shell.
Portable scripts generally use:
printf '%s\n' "$x" # print $x "unmolested" in POSIX shell
We could have chosen to respect echo -- $x, but YSH already has:
write -- $x # print $x "unmolested" in YSH
That means we also have:
echo $x # an even shorter way
So echo is technically superfluous in YSH, but it's also short, familiar, and
correct.
YSH isn't intended to be compatible with POSIX shell; only OSH is.
echo invocations I need to change when using YSH?A search like this can statically find most usages:
$ egrep -n 'echo (-e|-n|-en|-ne)' *.sh
test/syscall.sh:58: echo -n hi
test/syscall.sh:76: echo -e '\t'
$(dirname $x) and $[len(x)] ?Superficially, both of these syntaxes take an argument x and return a
string. But they are different:
$(dirname $x) is a shell command substitution that returns a string, and
starts another process.$[len(x)] is an expression sub containing a function call expression.
len(x) evaluates to an integer, and $[len(x)] converts it to
a string.${array[r'\']} ?This boils down to the difference between OSH and YSH, and not being able to
mix the two. Though they look similar, ${array[i]} syntax (with braces) is
fundamentally different than $[array[i]] syntax (with brackets).
${array[i]}.
${array[i++]} or
${assoc["$key"]}.r'\'.$[array[i]] is preferred.
$[array[i + 1] or $[mydict[key]].r'\' is a valid key, e.g. $[mydict[r'\']].Of course, YSH style is preferred when compatibility isn't an issue.
No:
echo ${array[r'\']}
Yes:
echo $[array[r'\']]
A similar issue exists with arithmetic.
Old:
echo $((1 + 2)) # shell arithmetic
New:
echo $[1 + 2] # YSH expression