| 1 | ---
|
| 2 | in_progress: true
|
| 3 | default_highlighter: oils-sh
|
| 4 | ---
|
| 5 |
|
| 6 | YSH I/O Builtins
|
| 7 | ================
|
| 8 |
|
| 9 | POSIX shell has overlapping and quirky constructs for doing I/O:
|
| 10 |
|
| 11 | - the builtins `echo`, `printf`, and `read`
|
| 12 | - the `$(command sub)` construct
|
| 13 | - Bash has `mapfile` and `readarray`
|
| 14 |
|
| 15 | YSH rationalizes I/O with:
|
| 16 |
|
| 17 | - A new `write` builtin
|
| 18 | - Long flags to `read`, like `--all`
|
| 19 | - The distinction between `$(string sub)` and `@(array sub)`
|
| 20 | - A set of data languages called [J8 Notation](j8-notation.html).
|
| 21 |
|
| 22 | YSH also has orthogonal mechanisms for string processing:
|
| 23 |
|
| 24 | - `${.myproc arg}` and `@{.myproc arg}` are an optimization (TODO)
|
| 25 | - `${x %.2f}` as a static version of the `printf` builtin (TODO)
|
| 26 | - `${x|html}` for safe escaping (TODO)
|
| 27 |
|
| 28 | These are discussed in more detail the [strings](strings.html) doc.
|
| 29 |
|
| 30 | <!-- TODO: should run all this code as in tour.md -->
|
| 31 |
|
| 32 | <div id="toc">
|
| 33 | </div>
|
| 34 |
|
| 35 | ## Problems With Shell
|
| 36 |
|
| 37 | - `echo` is flaky because `echo $x` is a bug. `$x` could be `-n`.
|
| 38 | - YSH `write` accepts `--`.
|
| 39 | - `read` is non-obvious because the `-r` flag to ignore `\` line continuations
|
| 40 | isn't the default. The `\` creates a mini-language that isn't understood by
|
| 41 | other line-based tools like `grep` and `awk`.
|
| 42 | - TODO: YSH should have a mechanism to read buffered lines.
|
| 43 | - There's no way to tell if `$()` strips the trailing newline,.
|
| 44 | - YSH has `read --all`, as well as lastpipe being on.
|
| 45 |
|
| 46 | Example:
|
| 47 |
|
| 48 | hostname | read --all (&x)
|
| 49 | write -- $x
|
| 50 |
|
| 51 | ## Summary of YSH features
|
| 52 |
|
| 53 | - `write`: `--qsn`, `--sep`, `--end`
|
| 54 | - `read`: `--all` (future: `--line`, `--all-lines`?)
|
| 55 | - `$(string sub)` removes the trailing newline, if any
|
| 56 | - `@(array sub)` splits by IFS
|
| 57 | - TODO: should it split by `IFS=$'\n'`?
|
| 58 |
|
| 59 | ### write
|
| 60 |
|
| 61 | - `-sep`: Characters to separate each argument. (Default: newline)
|
| 62 | - `-end`: Characters to terminate the whole invocation. (Default: newline)
|
| 63 | - `-n`: A synonym for `-end ''`.
|
| 64 |
|
| 65 | ## Buffered vs. Unbuffered
|
| 66 |
|
| 67 | - The POSIX flags to `read` issue many `read(0, 1)` calls. They do it
|
| 68 | byte-by-byte.
|
| 69 | - The `--long` flags to `read` use buffered I/O.
|
| 70 |
|
| 71 | ## Invariants
|
| 72 |
|
| 73 | Here are some design notes on making the I/O builtins orthogonal and
|
| 74 | composable. There should be clean ways to "round trip" data between the OS and
|
| 75 | YSH data structures.
|
| 76 |
|
| 77 | ### File -> String -> File
|
| 78 |
|
| 79 | cat input.txt | read --all
|
| 80 |
|
| 81 | # suppress the newline
|
| 82 | write --end '' $_reply > output.txt
|
| 83 |
|
| 84 | diff input.txt output.txt # should be equal
|
| 85 |
|
| 86 |
|
| 87 | ### File -> Array -> File
|
| 88 |
|
| 89 | TODO
|
| 90 |
|
| 91 | cat input.txt | read --all-lines :myarray
|
| 92 |
|
| 93 | # suppress the newline
|
| 94 | write --sep '' --end '' -- @myarray > output.txt
|
| 95 |
|
| 96 | diff input.txt output.txt # should be equal
|
| 97 |
|
| 98 | ### Array -> J8 Lines -> Array
|
| 99 |
|
| 100 | TODO
|
| 101 |
|
| 102 | ## Related
|
| 103 |
|
| 104 | - [JSON](json.html) support.
|