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.
|