Why Sponsor Oil? | source | all docs for version 0.12.9 | 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 readarrayOil rationalizes I/O with:
write builtinread, like --line and --all$(string sub) and @(array sub)Oil 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.
--.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, --endread: --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 Oil 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