Why Sponsor Oils? | source | all docs for version 0.20.0 | all versions | oilshell.org
Warning: Work in progress! Leave feedback on Zulip or Github if you'd like this doc to be updated.
POSIX shell has overlapping and quirky constructs for doing I/O:
echo
, printf
, and read
$(command sub)
constructmapfile
and readarray
YSH rationalizes I/O with:
write
builtinread
, like --line
and --all
$(string sub)
and @(array sub)
YSH also has orthogonal mechanisms for string processing:
${.myproc arg}
and @{.myproc arg}
are an optimization (TODO)${x %.2f}
as a static version of the printf
builtin (TODO)${x|html}
for safe escaping (TODO)These are discussed in more detail the strings doc.
echo
is flaky because echo $x
is a bug. $x
could be -n
.
write
accepts --
.read
is flaky good because the -r
flag to ignore \
line continuations
isn't the default. The \
creates a mini-language that isn't understood by
other line-based tools like grep
and awk
.
read --line
.$()
strips the trailing newline,.
read --all
, as well as lastpipe being on.Example:
hostname | read --all :x
write -- $x
write
: --qsn
, --sep
, --end
read
: --qsn
, --line
, --lines
, and --all
(or --all-lines
?)$(string sub)
removes the trailing newline, if any@(array sub)
splits by IFS
IFS=$'\n'
?-sep
: Characters to separate each argument. (Default: newline)-end
: Characters to terminate the whole invocation. (Default: newline)-n
: A synonym for -end ''
.read
issue many read(0, 1)
calls. They do it
byte-by-byte.--long
flags to read
use buffered I/O.Here are some design notes on making the I/O builtins orthogonal and composable. There should be clean ways to "round trip" data between the OS and YSH data structures.
# This will get messed up with newlines, and empty strings.
IFS=$'\n'
var lines1 = @(write -- @myarray)
# This will give you back an array
var lines2 = @(write --qsn -- @myarray)
This is one way to make a copy of an array
write --qsn -- @myarray | read --lines --qsn :otherarray
In contrast, this doesn't work when the elements have newlines:
var myarray = :| 'bad\n' |
write -- @myarray | read --lines :otherarray
cat input.txt | read --all-lines :myarray
# suppress the newline
write --sep '' --end '' -- @myarray > output.txt
diff input.txt output.txt # should be equal
cat input.txt | read --all :x
# suppress the newline
write --end '' $x > output.txt
diff input.txt output.txt # should be equal