OILS / doc / ref / chap-builtin-cmd.md View on Github | oils.pub

1854 lines, 1181 significant
1---
2title: Builtin Commands (Oils Reference)
3all_docs_url: ..
4body_css_class: width40
5default_highlighter: oils-sh
6preserve_anchor_case: yes
7---
8
9<div class="doc-ref-header">
10
11[Oils Reference](index.html) &mdash; Chapter **Builtin Commands**
12
13</div>
14
15This chapter in the [Oils Reference](index.html) describes builtin commands for OSH and YSH.
16
17<span class="in-progress">(in progress)</span>
18
19<div id="dense-toc">
20</div>
21
22## Memory
23
24### cmd/append
25
26Append word arguments to a list:
27
28 var mylist = :| hello |
29
30 append *.py (mylist) # append all Python files
31
32 var myflags = []
33 append -- -c 'echo hi' (myflags) # -- to avoid ambiguity
34
35It's a shortcut for:
36
37 call myflags->append('-c')
38 call myflags->append('echo hi')
39
40Similar names: [append][]
41
42[append]: chap-index.html#append
43
44### pp
45
46The `pp` builtin pretty prints values and interpreter state.
47
48Pretty printing expressions is the most common:
49
50 $ var x = 42
51 $ pp (x + 5)
52 myfile.ysh:1: (Int) 47 # print value with code location
53
54You can pass an unevaluated expression:
55
56 $ pp [x + 5]
57 myfile.ysh:1: (Int) 47 # evaluate first
58
59The `value` command is a synonym for the interactive `=` operator:
60
61 $ pp value (x)
62 (Int) 42
63
64 $ = x
65 (Int) 42
66
67Print proc names and doc comments:
68
69 $ pp proc # subject to change
70
71You can also print low-level interpreter state. The trailing `_` indicates
72that the exact format may change:
73
74Examples:
75
76 $ var x = :| one two |
77
78 $ pp asdl_ (x) # dump the ASDL "guts"
79
80 $ pp test_ (x) # single-line stable format, for spec tests
81
82 # dump the ASDL representation of a "Cell", which is a location for a value
83 # (not the value itself)
84 $ pp cell_ x
85
86
87## Handle Errors
88
89### error
90
91The `error` builtin interrupts shell execution.
92
93If there's a surrounding `try` block, the `_error` register is set, and
94execution proceeds after the block.
95
96Otherwise, the shell exits with a non-zero status.
97
98Examples:
99
100 error 'Missing /tmp' # program fails with status 10
101
102 try {
103 error 'Another problem'
104 }
105 echo $[error.code] # => 10
106
107Override the default error code of `10` with a named argument:
108
109 error 'Missing /tmp' (code=99) # program fails with status 99
110
111Named arguments add arbitrary properties to the resulting `_error` register:
112
113 error 'Oops' (path='foo.json')
114
115See [YSH Error Handling](../ysh-error-handling.html) for more examples.
116
117### failed
118
119A shortcut for `(_error.code !== 0)`:
120
121 try {
122 ls /tmp
123 }
124 if failed {
125 echo 'ls failed'
126 }
127
128It saves you 7 punctuation characters: `( _ . !== )`
129
130See [YSH Error Handling](../ysh-error-handling.html) for more examples.
131
132### try
133
134Run a block of code, stopping at the first error. (This is implemented with
135`shopt --set errexit`)
136
137`try` sets the `_error` register to a dict, and always returns 0.
138
139 try {
140 ls /nonexistent
141 }
142 if (_error.code !== 0) {
143 echo 'ls failed'
144 }
145
146Handle expression errors:
147
148 try {
149 var x = 42 / 0
150 }
151
152And errors from compound commands:
153
154 try {
155 ls | wc -l
156 diff <(sort left.txt) <(sort right.txt)
157 }
158
159The case statement can be useful:
160
161 try {
162 grep PATTERN FILE.txt
163 }
164 case (_error.code) {
165 (0) { echo 'found' }
166 (1) { echo 'not found' }
167 (else) { echo "grep returned status $[_error.code]" }
168 }
169
170See [YSH Error Handling](../ysh-error-handling.html) for more examples.
171
172### boolstatus
173
174Runs a command, and requires the exit code to be 0 or 1.
175
176 if boolstatus egrep '[0-9]+' myfile { # e.g. aborts on status 2
177 echo 'found' # status 0 means found
178 } else {
179 echo 'not found' # status 1 means not found
180 }
181
182It's meant for external commands that "return" more than 2 values, like true /
183false / fail, rather than pass / fail.
184
185### assert
186
187Evaluates and expression, and fails if it is not truthy.
188
189 assert (false) # fails
190 assert [false] # also fails (the expression is evaluated)
191
192It's common to pass an unevaluated expression with `===`:
193
194 func f() { return (42) }
195
196 assert [43 === f()]
197
198In this special case, you get a nicer error message:
199
200> Expected: 43
201> Got: 42
202
203That is, the left-hand side should be the expected value, and the right-hand
204side should be the actual value.
205
206## Shell State
207
208### ysh-cd
209
210It takes a block:
211
212 cd / {
213 echo $PWD
214 }
215
216### ysh-shopt
217
218Sets shell options, e.g.
219
220 shopt --unset errexit
221 shopt --set errexit
222
223You can set or unset multiple options with the groups `strict:all`,
224`ysh:upgrade`, and `ysh:all`. Example:
225
226 shopt --set ysh:upgrade
227
228If a block is passed, then:
229
2301. the mutated options are pushed onto a stack
2312. the block is executed
2323. the options are restored to their original state (even if the block fails to
233 execute)
234
235Example:
236
237 shopt --unset errexit {
238 false
239 echo 'ok'
240 }
241
242Note that setting `ysh:upgrade` or `ysh:all` may initialize the [ENV][] dict.
243
244Related: [shopt](#shopt)
245
246[ENV]: chap-special-var.html#ENV
247
248### shvar
249
250Execute a block with a global variable set.
251
252 shvar IFS=/ {
253 echo "ifs is $IFS"
254 }
255 echo "ifs restored to $IFS"
256
257### ctx
258
259Execute a block with a shared "context" that can be updated using the `ctx`
260built-in.
261
262 var mydict = {}
263 ctx push (mydict) {
264 # = mydict => {}
265 ctx set (mykey='myval')
266 }
267 # = mydict => { mykey: 'myval' }
268
269The context can be modified with `ctx set (key=val)`, which updates or inserts
270the value at the given key.
271
272The context can also be updated with `ctx emit field (value)`.
273
274 ctx push (mydict) {
275 # = mydict => {}
276 ctx emit mylist (0)
277 # = mydict => { mylist: [0] }
278 ctx emit mylist (1)
279 }
280 # = mydict => { mylist: [0, 1] }
281
282Contexts can be nested, resulting in a stack of contexts.
283
284 ctx push (mydict1) {
285 ctx set (dict=1)
286 ctx push (mydict2) {
287 ctx set (dict=2)
288 }
289 }
290 # = mydict1 => { dict: 1 }
291 # = mydict2 => { dict: 2 }
292
293`ctx` is useful for creating DSLs, such as a mini-parseArgs.
294
295 proc parser (; place ; ; block_def) {
296 var p = {}
297 ctx push (p, block_def)
298 call place->setValue(p)
299 }
300
301 proc flag (short_name, long_name; type; help) {
302 ctx emit flag ({short_name, long_name, type, help})
303 }
304
305 proc arg (name) {
306 ctx emit arg ({name})
307 }
308
309 parser (&spec) {
310 flag -t --tsv (Bool, help='Output as TSV')
311 flag -r --recursive (Bool, help='Recurse into the given directory')
312 flag -N --count (Int, help='Process no more than N files')
313 arg path
314 }
315
316### push-registers
317
318Save global registers like $? on a stack. It's useful for preventing plugins
319from interfering with user code. Example:
320
321 status_42 # returns 42 and sets $?
322 push-registers { # push a new frame
323 status_43 # top of stack changed here
324 echo done
325 } # stack popped
326 echo $? # 42, read from new top-of-stack
327
328Current list of registers:
329
330 Regex data underlying BASH_REMATCH, _group(), _start(), _end()
331 $?
332 _error # set by the try builtin
333 PIPESTATUS # aka _pipeline_status
334 _process_sub_status
335
336
337## Modules
338
339### source-guard
340
341Registers a name in the global "module" dict. Returns 0 if it doesn't exist,
342or 1 if it does.
343
344Use it like this in executable files:
345
346 source-guard main || return 0
347
348And like this in libraries:
349
350 source-guard myfile.ysh || return 0
351
352### is-main
353
354The `is-main` builtin returns 1 (false) if the current file was executed with
355the `source` builtin.
356
357In the "main" file, including `-c` or `stdin` input, it returns 0 (true).
358
359Use it like this:
360
361 if is-main {
362 runproc @ARGV
363 }
364
365### use
366
367The `use` builtin evaluates a source file in a new `Frame`, and then creates an
368`Obj` that is a namespace.
369
370 use my-dir/mymodule.ysh
371
372 echo $[mymodule.my_integer] # the module Obj has attributes
373 mymodule my-proc # the module Obj is invokable
374
375The evaluation of such files is cached, so it won't be re-evaluated if `use` is
376called again.
377
378To import a specific name, use the `--pick` flag:
379
380 use my-dir/mymodule.ysh --pick my-proc other-proc
381
382 my-proc 1 2
383 other-proc 3 4
384
385Note: the `--pick` flag must come *after* the module, so this isn't valid:
386
387 use --pick my-proc mymodule.sh # INVALID
388
389<!--
390# TODO:
391
392use mod.ysh --all-provided # relies on __provide__ or provide builtin
393use mod.ysh --all-for-testing
394-->
395
396---
397
398The `--extern` flag means that `use` does nothing. These commands can be used
399by tools to analyze names.
400
401 use --extern grep sed awk
402
403---
404
405Notes:
406
407- To get a reference to `module-with-hyphens`, you may need to use
408 `getVar('module-with-hyphens')`.
409 - TODO: consider backtick syntax as well
410- `use` must be used at the top level, not within a function.
411 - This behavior is unlike Python.
412- The `use` builtin populates the new module with references to these values in
413 the calling module:
414 - [ENV][] - to mutate and set environment vars
415 - [PS4][] - for cross-module tracing in OSH
416
417[ENV]: chap-special-var.html#ENV
418[PS4]: chap-plugin.html#PS4
419
420Warnings:
421
422- `use` **copies** the module bindings into a new `Obj`. This means that if
423 you rebind `mymodule.my_integer`, it will **not** be visible to code in the
424 module.
425 - This behavior is unlike Python.
426- `use` allows "circular imports". That is `A.ysh` can `use B.ysh`, and vice
427 versa.
428 - To eliminate confusion over uninitialized names, use **only** `const`,
429 `func`, and `proc` at the top level of `my-module.ysh`. Don't run
430 commands, use `setvar`, etc.
431
432## I/O
433
434### ysh-read
435
436YSH adds long flags to shell's `read`. These two flags are fast and
437recommended:
438
439 read --all # whole file including trailing \n, fills $_reply
440 read --all (&x) # fills $x
441
442 read --num-bytes 3 # read N bytes, fills _reply
443 read --num-bytes 3 (&x) # fills $x
444
445---
446
447This flag replaces shell's `IFS= read -r` idiom, reading one byte a time in an
448unbuffered fashion:
449
450 read --raw-line # unbuffered read of line, omitting trailing \n
451 read --raw-line (&x) # fills $x
452
453 read --raw-line --with-eol # include the trailing \n
454
455A loop over [io.stdin][] allows buffered reading of lines, which is faster.
456
457[io.stdin]: chap-type-method.html#stdin
458
459You may want to use `fromJson8()` or `fromJson()` after reading a line.
460
461---
462
463The `-0` flag also reads one byte at a time:
464
465 read -0 # read until NUL, synonym for read -r -d ''
466
467Notes:
468
469- Unlike OSH [read](#read), none of these features remove NUL bytes.
470- Performance summary: [YSH Input/Output > Three Types of I/O][ysh-io-three]
471
472[ysh-io-three]: ../ysh-io.html#three-types-of-io
473
474<!--
475
476TODO:
477
478- read --netstr
479- io.stdin0 coudl be a buffered version of read -0 ?
480- JSON
481 - @() is related - it reads J8 lines
482 - JSON lines support?
483 - fromJ8Line() is different than from fromJson8() ? It's like @()
484
485-->
486
487<!--
488
489What about write? These would be the same:
490
491 write --json -- $s
492 write --j8 -- $s
493
494 write -- $[toJson(s)]
495 write -- $[toJson8(s)]
496
497 write --json -- @strs
498 write --j8 -- @strs
499
500 write -- @[toJson(s) for s in strs]
501 write -- @[toJson8(s) for s in strs]
502
503It's an argument for getting rid --json and --j8? I already implemented them,
504but it makes the API smaller.
505
506I guess the main thing would be to AVOID quoting sometimes?
507
508 $ write --j8 -- unquoted
509 unquoted
510
511 $ write --j8 -- $'\'' '"'
512 "'"
513 "\""
514
515I think this could be the shell style?
516
517 $ write --shell-str -- foo bar baz
518
519Or it could be
520
521 $ write -- @[toShellString(s) for s in strs]
522
523I want this to be "J8 Lines", but it can be done in pure YSH. It's not built
524into the interpreter.
525
526 foo/bar
527 "hi"
528b'hi'
529u'hi'
530
531But what about
532
533 Fool's Gold
534a'hi' # This feels like an error?
535a"hi" # what about this?
536
537Technically we CAN read those as literal strings
538-->
539
540### ysh-echo
541
542Print arguments to stdout, separated by a space.
543
544 ysh$ echo hi there
545 hi there
546
547The [simple_echo][] option means that flags aren't accepted, and `--` is not
548accepted.
549
550 ysh$ echo -n
551 -n
552
553See the [YSH FAQ entry on echo][echo-en] for details.
554
555[simple_echo]: chap-option.html#ysh:all
556[echo-en]: ../ysh-faq.html#how-do-i-write-the-equivalent-of-echo-e-or-echo-n
557
558### ysh-test
559
560The YSH [test](#test) builtin supports these long flags:
561
562 --dir same as -d
563 --exists same as -e
564 --file same as -f
565 --symlink same as -L
566
567 --true Is the argument equal to the string "true"?
568 --false Is the argument equal to the string "false"?
569
570The `--true` and `--false` flags can be used to combine commands and
571expressions:
572
573 if test --file a && test --true $[bool(mydict)] {
574 echo ok
575 }
576
577This works because the boolean `true` *stringifies* to `"true"`, and likewise
578with `false`.
579
580That is, `$[true] === "true"` and `$[false] === "false"`.
581
582### write
583
584write fixes problems with shell's `echo` builtin.
585
586The default separator is a newline, and the default terminator is a
587newline.
588
589Examples:
590
591 write -- ale bean # write two lines
592
593 write -n -- ale bean # synonym for --end '', like echo -n
594 write --sep '' --end '' -- a b # write 2 bytes
595 write --sep $'\t' --end $'\n' -- a b # TSV line
596
597You may want to use `toJson8()` or `toJson()` before writing:
598
599 write -- $[toJson8(mystr)]
600 write -- $[toJson(mystr)]
601
602
603<!--
604 write --json -- ale bean # JSON encode, guarantees two lines
605 write --j8 -- ale bean # J8 encode, guarantees two lines
606-->
607
608
609### fork
610
611Run a command, but don't wait for it to finish.
612
613 fork { sleep 1 }
614 wait -n
615
616In YSH, use `fork` rather than shell's `&` ([ampersand][]).
617
618[ampersand]: chap-cmd-lang.html#ampersand
619
620### forkwait
621
622The preferred alternative to shell's `()`. Prefer `cd` with a block if possible.
623
624 forkwait {
625 not_mutated=zzz
626 }
627 echo $not_mutated
628
629### redir
630
631Runs a block passed to it. It's designed to enable a **prefix** syntax when
632redirecting:
633
634 redir >out.txt {
635 echo 1
636 echo 2
637 }
638
639When a block is long, it's more readable than shell's postfix style:
640
641 { echo 1
642 echo 2
643 } >out.txt
644
645## Private
646
647Private builtins are not enabled by default:
648
649 sleep 0.1 # runs external process; private builtin not found
650 builtin sleep 0.1 # runs private builtin
651
652### cat
653
654`cat` is a *private* builtin that reads from files and writes to stdout.
655
656 cat FILE+ # Read from each file, and write to stdout
657 # If the file is -, read from stdin (not the file called -)
658 cat # equivalent to cat -
659
660- Related: [rewrite_extern][], [ysh_rewrite_extern][]
661
662[rewrite_extern]: chap-option.html#rewrite_extern
663[ysh_rewrite_extern]: chap-option.html#ysh_rewrite_extern
664
665### rm
666
667`rm` is a *private* builtin that removes files.
668
669 rm FLAG* FILE*
670
671Flags:
672
673 -f Don't fail if the file exist, and don't fail if no arguments are
674 passed.
675
676Return 0 on success, and non-zero otherwise.
677
678- Related: [rewrite_extern][]
679
680### sleep
681
682`sleep` is a *private* builtin that puts the shell process to sleep for the
683given number of seconds.
684
685Example:
686
687 builtin sleep 0.1 # wait 100 milliseconds
688
689It respects signals:
690
691- `SIGINT` / Ctrl-C cancels the command, with the standard behavior:
692 - in an interactive shell, you return to the prompt
693 - a non-interactive shell is cancelled
694- Upon receiving other signals, Oils run pending traps, and then continues to
695 sleep.
696
697It's compatible with the POSIX `sleep` utility:
698
699 sleep 2 # wait 2 seconds
700
701## Hay Config
702
703### hay
704
705### haynode
706
707
708## Data Formats
709
710### json
711
712Write JSON:
713
714 var d = {name: 'bob', age: 42}
715 json write (d) # default indent of 2, type errors
716 json write (d, space=0) # no indent
717 json write (d, type_errors=false) # non-serializable types become null
718 # (e.g. Obj, Proc, Eggex)
719
720Read JSON:
721
722 echo hi | json read # fills $_reply by default
723
724Or use an explicit place:
725
726 var x = ''
727 json read (&x) < myfile.txt
728
729Related: [err-json-encode][] and [err-json-decode][]
730
731[err-json-encode]: chap-errors.html#err-json-encode
732[err-json-decode]: chap-errors.html#err-json-decode
733
734### json8
735
736Like `json`, but on the encoding side:
737
738- Falls back to `b'\yff'` instead of lossy Unicode replacement char
739
740On decoding side:
741
742- Understands `b'' u''` strings
743
744Related: [err-json8-encode]() and [err-json8-decode]()
745
746[err-json8-encode]: chap-errors.html#err-json8-encode
747[err-json8-decode]: chap-errors.html#err-json8-decode
748
749## I/O
750
751These builtins take input and output. They're often used with redirects.
752
753### read
754
755 read FLAG* VAR*
756
757Read input from `stdin`, and assign pieces of input to variables. Without
758flags, `read` uses this algorithm:
759
7601. Read bytes from `stdin`, one at a time, until a newline `\n`.
761 - Respect `\` escapes and line continuations.
762 - Any NUL bytes are removed from the input.
7631. Use the `$IFS` algorithm to split the line into N pieces, where `N` is the
764 number of `VAR` specified. Each piece is assigned to the corresponding
765 variable.
766 - If no VARs are given, assign to the `$REPLY` var.
767
768The `-r` flag is useful to disable backslash escapes.
769
770POSIX mandates the slow behavior of reading one byte at a time. In YSH, you
771can avoid this by using [io.stdin][], or a `--long-flag` documented in
772[ysh-read](#ysh-read).
773
774Flags:
775
776 -a ARRAY assign the tokens to elements of this array
777 -d CHAR use DELIM as delimiter, instead of newline
778 -n NUM read up to NUM characters, respecting delimiters. When -r is not
779 specified, backslash escape of the form "\?" is counted as one
780 character. This is the Bash behavior, but other shells such as
781 ash and mksh count the number of bytes with "-n" without
782 considering backslash escaping.
783 -p STR print the string PROMPT before reading input
784 -r raw mode: don't let backslashes escape characters
785 -s silent: do not echo input coming from a terminal
786 -t NUM time out and fail after TIME seconds
787 -t 0 returns whether any input is available
788 -u FD read from file descriptor FD instead of 0 (stdin)
789
790 <!-- -N NUM read up to NUM characters, ignoring delimiters -->
791 <!-- -e use readline to obtain the line
792 -i STR use STR as the initial text for readline -->
793
794Performance summary: [YSH Input/Output > Three Types of I/O][ysh-io-three]
795
796### echo
797
798 echo FLAG* ARG*
799
800Prints ARGs to stdout, separated by a space, and terminated by a newline.
801
802Flags:
803
804 -e enable interpretation of backslash escapes
805 -n omit the trailing newline
806<!-- -E -->
807
808`echo` in YSH does **not** accept these flags. See [ysh-echo](#ysh-echo) and
809[the FAQ entry][echo-en]. (This is unusual because YSH doesn't usually "break"
810OSH.)
811
812See [char-escapes](chap-mini-lang.html#char-escapes) to see what's supported
813when `-e` is passed.
814
815### printf
816
817 printf FLAG* FMT ARG*
818
819Formats values and prints them. The FMT string contain three types of objects:
820
8211. Literal Characters
8222. Character escapes like `\t`. See [char-escapes](chap-mini-lang.html#char-escapes).
8233. Percent codes like `%s` that specify how to format each each ARG.
824
825If not enough ARGS are passed, the empty string is used. If too many are
826passed, the FMT string will be "recycled".
827
828Flags:
829
830 -v VAR Write output in variable VAR instead of standard output.
831
832Format specifiers:
833
834 %% Prints a single "%".
835 %b Interprets backslash escapes while printing.
836 %q Prints the argument escaping the characters needed to make it reusable
837 as shell input.
838 %d Print as signed decimal number.
839 %i Same as %d.
840 %o Print as unsigned octal number.
841 %u Print as unsigned decimal number.
842 %x Print as unsigned hexadecimal number with lower-case hex-digits (a-f).
843 %X Same as %x, but with upper-case hex-digits (A-F).
844 %f Print as floating point number.
845 %e Print as a double number, in "±e" format (lower-case e).
846 %E Same as %e, but with an upper-case E.
847 %g Interprets the argument as double, but prints it like %f or %e.
848 %G Same as %g, but print it like %E.
849 %c Print as a single char, only the first character is printed.
850 %s Print as string
851 %n The number of characters printed so far is stored in the variable named
852 in the argument.
853 %a Interprets the argument as double, and prints it like a C99 hexadecimal
854 floating-point literal.
855 %A Same as %a, but print it like %E.
856 %(FORMAT)T Prints date and time, according to FORMAT as a format string
857 for strftime(3). The argument is the number of seconds since
858 epoch. It can also be -1 (current time, also the default value
859 if there is no argument) or -2 (shell startup time).
860
861### readarray
862
863Alias for `mapfile`.
864
865### mapfile
866
867 mapfile FLAG* ARRAY?
868
869Reads lines from stdin into the variable named ARRAY (default
870`${MAPFILE[@]}`).
871
872Flags:
873
874 -t Remove the trailing newline from every line
875<!--
876 -d CHAR use CHAR as delimiter, instead of the default newline
877 -n NUM copy up to NUM lines
878 -O NUM begins copying lines at the NUM element of the array
879 -s NUM discard the first NUM lines
880 -u FD read from FD file descriptor instead of the standard input
881 -C CMD run CMD every NUM lines specified in -c
882 -c NUM every NUM lines, the CMD command in C will be run
883-->
884
885## Run Code
886
887These builtins accept shell code and run it.
888
889### source
890
891 source SCRIPT ARG*
892
893Execute SCRIPT with the given ARGs, in the context of the current shell. That is,
894existing variables will be modified.
895
896---
897
898Oils extension: If the SCRIPT starts with `///`, we look for scripts embedded in
899the `oils-for-unix` binary. Example:
900
901 source ///osh/two.sh # load embedded script
902
903 : ${LIB_OSH=fallback/dir}
904 source $LIB_OSH/two.sh # same thing
905
906The [LIB_OSH][] form is useful for writing a script that works under both bash
907and OSH.
908
909- Related: the [cat-em][] tool prints embedded scripts.
910
911[LIB_OSH]: chap-special-var.html#LIB_OSH
912[cat-em]: chap-front-end.html#cat-em
913
914
915### cmd/eval
916
917 eval ARG+
918
919Creates a string by joining ARGs with a space, then runs it as a shell command.
920
921Example:
922
923 # Create the string echo "hello $name" and run it.
924 a='echo'
925 b='"hello $name"'
926 eval $a $b
927
928Tips:
929
930- Using `eval` can confuse code and user-supplied data, leading to [security
931issues][].
932- Prefer passing single string ARG to `eval`.
933
934[security issues]: https://mywiki.wooledge.org/BashFAQ/048
935
936### trap
937
938The `trap` builtin lets you run shell code when events happen. Events are
939signals or shell interpreter hooks.
940
941These forms print the current `trap` state:
942
943 trap -l # List all events and their number
944 trap -p # Print the current trap state: events and handlers
945
946These forms modify the `trap` state:
947
948 trap CMD EVENT* # Register handler for the given events
949 trap - EVENT* # Remove handler for the given events (SIG_DFL)
950 trap '' EVENT* # Do nothing for the given events (SIG_IGN)
951
952Examples:
953
954 trap 'echo hi' EXIT INT # Register
955 trap - EXIT INT # Remove
956 trap '' EXIT INT # Ignore
957
958OSH also support legacy syntax, which is not recommended:
959
960 trap 'echo hi' 0 # 0 is the exit trap
961 trap INT # remove signal handler
962 trap 0 # remove exit trap
963 trap 0 INT # remove both
964
965Tips:
966
967- Prefer passing the name of a shell function to `trap`.
968 - See [ysh-trap](#ysh-trap) for even nicer idioms.
969- See [Chapter: Plugins and Hooks > Traps](chap-plugin.html#Traps) for a list
970 of traps, like `trap '' EXIT`.
971
972### ysh-trap
973
974The `trap` builtin lets you run shell code when events happen. YSH improves
975the syntax of the trap builtin, and removes legacy.
976
977These forms print the current `trap` state:
978
979 trap -l # List all events and their number
980 trap -p # Print the current trap state: events and handlers
981
982These forms modify the `trap` state:
983
984 trap --add EVENT* BLOCK # Register handlers
985 trap --remove EVENT* # Remove handlers (SIG_DFL)
986 trap --ignore EVENT* # Remove handlers (SIG_IGN)
987
988Examples:
989
990 trap --add EXIT INT {
991 echo 'either exit'
992 echo 'or int'
993 }
994
995 trap --remove EXIT INT
996 trap --ignore EXIT INT
997
998Note: the block argument to `trap --add` doesn't capture variables -- it's not
999a closure. So YSH behaves like OSH, but the syntax doesn't encourage putting
1000source code in strings.
1001
1002## Set Options
1003
1004The `set` and `shopt` builtins set global shell options. YSH code should use
1005the more natural `shopt`.
1006
1007### set
1008
1009 set FLAG* ARG*
1010
1011Sets global shell options. Short style:
1012
1013 set -e
1014
1015Long style:
1016
1017 set -o errexit
1018
1019Set the arguments array:
1020
1021 set -- 1 2 3
1022
1023See [Chapter: Global Shell Options](chap-option.html) for a list of options.
1024
1025### shopt
1026
1027 shopt FLAG* OPTION* BLOCK?
1028
1029Sets global shell options.
1030
1031Flags:
1032
1033 -s --set Turn the named options on
1034 -u --unset Turn the named options off
1035 -p Print option values, and 1 if any option is unset
1036 -o Use older set of options, normally controlled by 'set -o'
1037 -q Return 0 if the option is true, else 1
1038
1039This command is compatible with `shopt` in bash. See [ysh-shopt](#ysh-shopt) for
1040details on YSH enhancements.
1041
1042See [Chapter: Global Shell Options](chap-option.html) for a list of options.
1043
1044## Working Dir
1045
1046These 5 builtins deal with the working directory of the shell.
1047
1048### cd
1049
1050 cd FLAG* DIR
1051
1052Changes the working directory of the current shell process to DIR.
1053
1054If DIR isn't specified, change to `$HOME`. If DIR is `-`, change to `$OLDPWD`
1055(a variable that the sets to the previous working directory.)
1056
1057Flags:
1058
1059 -L Follow symbolic links, i.e. change to the TARGET of the symlink.
1060 (default).
1061 -P Don't follow symbolic links.
1062
1063### chdir
1064
1065`chdir` is a synonym for `cd`. Shells like `busybox ash` support it, so OSH
1066does too.
1067
1068### pwd
1069
1070 pwd FLAG*
1071
1072Prints the current working directory.
1073
1074Flags:
1075
1076 -L Follow symbolic links if present (default)
1077 -P Don't follow symbolic links. Print the link instead of the target.
1078
1079### pushd
1080
1081<!--pushd FLAGS DIR-->
1082 pushd DIR
1083<!--pushd +/-NUM-->
1084
1085Add DIR to the directory stack, then change the working directory to DIR.
1086Typically used with `popd` and `dirs`.
1087
1088<!--FLAGS:
1089 -n Don't change the working directory, just manipulate the stack
1090NUM:
1091 Rotates the stack the number of places specified. Eg, given the stack
1092 '/foo /bar /baz', where '/foo' is the top of the stack, pushd +1 will move
1093 it to the bottom, '/bar /baz /foo'-->
1094
1095### popd
1096
1097 popd
1098
1099Removes a directory from the directory stack, and changes the working directory
1100to it. Typically used with `pushd` and `dirs`.
1101
1102### dirs
1103
1104 dirs FLAG*
1105
1106Shows the contents of the directory stack. Typically used with `pushd` and
1107`popd`.
1108
1109Flags:
1110
1111 -c Clear the dir stack.
1112 -l Show the dir stack, but with the real path instead of ~.
1113 -p Show the dir stack, but formatted as one line per entry.
1114 -v Like -p, but numbering each line.
1115
1116## Completion
1117
1118These builtins implement our bash-compatible autocompletion system.
1119
1120### complete
1121
1122Registers completion policies for different commands.
1123
1124### compgen
1125
1126Generates completion candidates inside a user-defined completion function.
1127
1128It can also be used in scripts, i.e. outside a completion function.
1129
1130### compopt
1131
1132Changes completion options inside a user-defined completion function.
1133
1134### compadjust
1135
1136Adjusts `COMP_ARGV` according to specified delimiters, and optionally set
1137variables cur, prev, words (an array), and cword. May also set 'split'.
1138
1139This is an OSH extension that makes it easier to run the bash-completion
1140project.
1141
1142### compexport
1143
1144Complete an entire shell command string. For example,
1145
1146 compexport -c 'echo $H'
1147
1148will complete variables like `$HOME`. And
1149
1150 compexport -c 'ha'
1151
1152will complete builtins like `hay`, as well as external commands.
1153
1154
1155## Shell Process
1156
1157These builtins mutate the state of the shell process.
1158
1159### exec
1160
1161 exec BIN_PATH ARG*
1162
1163Replaces the running shell with the binary specified, which is passed ARGs.
1164BIN_PATH must exist on the file system; i.e. it can't be a shell builtin or
1165function.
1166
1167### umask
1168
1169Manage the bit mask that determines the permission metadata on new files and
1170directories.
1171
1172 umask FLAG? # print the current mask
1173
1174 umask OCTAL # set the mask, e.g. umask 0124
1175
1176 umask SYMBOLIC # set the mask, e.g. umask u+w
1177
1178Flags:
1179
1180 -p Print the mask in a form that may be reused as input
1181
1182#### How Masks Work
1183
1184Let's walk through an example. A common `umask` is `0022`. This is three
1185**octal** digits corresponding to:
1186
1187 0 2 2
1188 ^user ^group ^other
1189 write write
1190
1191Each octal digit has 3 bits:
1192
1193 1 execute
1194 2 write
1195 4 read
1196
1197For example, 7 is equal to 1 + 2 + 4, so 7 represents the set of 3 bits `r w
1198x`.
1199
1200---
1201
1202The mask is subtracted from 666 for files:
1203
1204 666 # rw-rw-rw- (not executable)
1205 - 022
1206 -----
1207 644 # rw-r--r--
1208
1209And 777 for directories:
1210
1211 777 # rwxrwxrwx
1212 - 022
1213 -----
1214 755 # rwxr-xr-x
1215
1216<!--
1217Not implemented:
1218 -S print the mask in symbolic form
1219-->
1220
1221#### Symbolic Masks
1222
1223Rather than specifying an octal mask, you can modify the umask with list of
1224comma-separated **symbolic** clauses, like:
1225
1226 umask ug=rwx,o-r
1227
1228Each clause is of the form:
1229
1230 who* (operator permission*)* # this format is accepted by chmod
1231
1232**Who** is a set, determining which sections of the mask to modify:
1233
1234 ugo user, group, or other
1235 a Modify all bits, equivalent to 'ugo'
1236
1237**Operator** determines how to apply the permissions:
1238
1239 + Entries will be created with the permissions
1240 - Entries will be created without the permission
1241 = Set the umask to (0777 - permissions)
1242
1243**Permission** is a set, determining what can be done with the entry:
1244
1245 rwx Set the read, write, or execute bit respectively
1246 X Set the execute bit iff the umask before this operation has one of its
1247 3 execute bits set
1248 st Does nothing, but exists for POSIX compatibility
1249 ugo Set permission equal to the umask's u, g, and o bits before this
1250 operation
1251
1252We can also express the syntax like this:
1253
1254 [ugoa]*([-+=]([rwxXstugo]*))*
1255
1256
1257#### Examples
1258
1259 umask # print the current umask in octal form
1260
1261 umask u+rwx-x-w-r # operators can be chained
1262
1263 umask a=u # [ugo] after the operator represents the initial umask
1264
1265 umask =u # equivalent to 'umask a=u'
1266
1267### ulimit
1268
1269 ulimit --all
1270 ulimit -a
1271 ulimit FLAGS* -RESOURCE_FLAG VALUE?
1272
1273 ulimit FLAGS* VALUE? # discouraged
1274
1275Show and modify process resource limits.
1276
1277Flags:
1278
1279 -S for soft limit
1280 -H for hard limit
1281
1282 -c -d -f ... # ulimit --all shows all resource flags
1283
1284Show a table of resources:
1285
1286 ulimit --all
1287 ulimit -a
1288
1289For example, the table shows that `-n` is the flag that controls the number
1290file descriptors, the soft and hard limit for `-n`, and the multiplication
1291"factor" for the integer VALUE you pass.
1292
1293---
1294
1295Here are examples of using resource flags.
1296
1297Get the soft limit for the number of file descriptors:
1298
1299 ulimit -S -n
1300 ulimit -n # same thing
1301
1302Get the hard limit:
1303
1304 ulimit -H -n
1305
1306Set the soft or hard limit:
1307
1308 ulimit -S -n 100
1309 ulimit -H -n 100
1310
1311Set both limits:
1312
1313 ulimit -n 100
1314
1315A special case that's discouraged: with no resource flag, `-f` is assumed:
1316
1317 ulimit # equivalent to ulimit -f
1318 ulimit 100 # equivalent to ulimit -f 100
1319
1320### times
1321
1322 times
1323
1324Shows the user and system time used by the shell and its child processes.
1325
1326## Child Process
1327
1328### jobs
1329
1330 jobs
1331
1332Shows all jobs running in the shell and their status.
1333
1334### wait
1335
1336Wait for jobs to finish, in a few different ways. (A job is a process or a
1337pipeline.)
1338
1339 wait # no arguments
1340
1341Wait for all jobs to terminate. The exit status is 0, unless a signal occurs.
1342
1343 wait -n
1344
1345Wait for the next job to terminate, and return its status.
1346
1347 wait $pid1 $pid2 ...
1348
1349Wait for the jobs specified by PIDs to terminate. Return the status of the
1350last one.
1351
1352 wait %3 %2 ...
1353
1354Wait for the jobs specified by "job specs" to terminate. Return the status of
1355the last one.
1356
1357---
1358
1359If wait is interrupted by a signal, the exit status is the signal number + 128.
1360
1361---
1362
1363When using `set -e` aka `errexit`, `wait --all` is useful. See topic
1364[ysh-wait](#ysh-wait).
1365
1366<!--
1367The ARG can be a PID (tracked by the kernel), or a job number (tracked by the
1368shell). Specify jobs with the syntax `%jobnumber`.
1369-->
1370
1371### ysh-wait
1372
1373YSH extends the `wait` builtin with 2 flags:
1374
1375 wait --all # wait for all jobs, like 'wait'
1376 # but exit 1 if any job exits non-zero
1377
1378 wait --verbose # show a message on each job completion
1379
1380 wait --all --verbose # show a message, and also respect failure
1381
1382### fg
1383
1384 fg JOB?
1385
1386Continues a stopped job in the foreground. This means it can receive signals
1387from the keyboard, like Ctrl-C and Ctrl-Z.
1388
1389If no JOB is specified, use the latest job.
1390
1391### bg
1392
1393UNIMPLEMENTED
1394
1395 bg JOB?
1396
1397Continues a stopped job, while keeping it in the background. This means it
1398**can't** receive signals from the keyboard, like Ctrl-C and Ctrl-Z.
1399
1400If no JOB is specified, use the latest job.
1401
1402### kill
1403
1404The `kill` builtin sends a signal to one or more processes. Usage:
1405
1406 kill (-s SIG | -SIG)? WHAT+ # send SIG to the given processes
1407
1408where
1409
1410 SIG = NAME | NUMBER # e.g. USR1 or 10
1411 WHAT = PID | JOBSPEC # e.g. 789 or %%
1412
1413Examples:
1414
1415 kill -s USR1 789 # send SIGUSR1 to PID 789
1416
1417 kill -s USR1 789 %% # send signal to PID 789 and the current job
1418 kill -s 10 789 %% # specify SIGUSR1 by number instead
1419
1420 kill -USR1 789 %% # shortcut syntax
1421 kill -10 789 %% # shortcut using a number
1422
1423 kill -n USR1 789 %% # -n is a synonym for -s
1424 kill 789 %% # if not specified, the default is SIGTERM
1425
1426---
1427
1428It can also list signals:
1429
1430 kill -L # List all signals
1431 kill -L SIG+ # Translate signals from name to number, and vice versa
1432
1433Examples:
1434
1435 kill -l # List all signals; -l is a synonym for -L
1436 kill -L USR1 USR2 # prints '10 12'
1437 kill -L USR1 15 # prints '10 TERM'
1438 kill -L 134 # you can also pass exit codes, this prints 'ABRT'
1439
1440## External
1441
1442### test
1443
1444 test OP ARG
1445 test ARG OP ARG
1446 [ OP ARG ] # [ is an alias for test that requires closing ]
1447 [ ARG OP ARG ]
1448
1449Evaluates a conditional expression and returns 0 (true) or 1 (false).
1450
1451Note that `[` is the name of a builtin, not an operator in the language. Use
1452`test` to avoid this confusion.
1453
1454String expressions:
1455
1456 -n STR True if STR is not empty.
1457 'test STR' is usually equivalent, but discouraged.
1458 -z STR True if STR is empty.
1459 STR1 = STR2 True if the strings are equal.
1460 STR1 != STR2 True if the strings are not equal.
1461 STR1 < STR2 True if STR1 sorts before STR2 lexicographically.
1462 STR1 > STR2 True if STR1 sorts after STR2 lexicographically.
1463 Note: < and > should be quoted like \< and \>
1464
1465File expressions:
1466
1467 -a FILE Synonym for -e.
1468 -b FILE True if FILE is a block special file.
1469 -c FILE True if FILE is a character special file.
1470 -d FILE True if FILE is a directory.
1471 -e FILE True if FILE exists.
1472 -f FILE True if FILE is a regular file.
1473 -g FILE True if FILE has the sgid bit set.
1474 -G FILE True if current user's group is also FILE's group.
1475 -h FILE True if FILE is a symbolic link.
1476 -L FILE True if FILE is a symbolic link.
1477 -k FILE True if FILE has the sticky bit set.
1478 -O FILE True if current user is the file owner.
1479 -p FILE True if FILE is a named pipe (FIFO).
1480 -r FILE True if FILE is readable.
1481 -s FILE True if FILE has size bigger than 0.
1482 -S FILE True if FILE is a socket file.
1483 -t FD True if file descriptor FD is open and refers to a terminal.
1484 -u FILE True if FILE has suid bit set.
1485 -w FILE True if FILE is writable.
1486 -x FILE True if FILE is executable.
1487 FILE1 -nt FILE2 True if FILE1 is newer than FILE2 (mtime).
1488 FILE1 -ot FILE2 True if FILE1 is older than FILE2 (mtime).
1489 FILE1 -ef FILE2 True if FILE1 is a hard link to FILE2.
1490<!-- -N FILE True if FILE was modified since last read (mtime newer than atime).-->
1491
1492Arithmetic expressions coerce arguments to integers, then compare:
1493
1494 INT1 -eq INT2 True if they're equal.
1495 INT1 -ne INT2 True if they're not equal.
1496 INT1 -lt INT2 True if INT1 is less than INT2.
1497 INT1 -le INT2 True if INT1 is less or equal than INT2.
1498 INT1 -gt INT2 True if INT1 is greater than INT2.
1499 INT1 -ge INT2 True if INT1 is greater or equal than INT2.
1500
1501Other expressions:
1502
1503 -o OPTION True if the shell option OPTION is set.
1504 -v VAR True if the variable VAR is set.
1505
1506The test builtin also supports POSIX conditionals like -a, -o, !, and ( ), but
1507these are discouraged.
1508
1509<!-- -R VAR True if the variable VAR has been set and is a nameref variable. -->
1510
1511---
1512
1513See [ysh-test](#ysh-test) for log flags like `--file` and `--true`.
1514
1515### getopts
1516
1517 getopts SPEC VARNAME ARG*
1518
1519A single iteration of flag parsing. The SPEC is a sequence of flag characters,
1520with an optional `:` to which means that the flag takes an argument:
1521
1522 ab # accept -a and -b
1523 xy:z # accept -x, -y arg, and -z
1524
1525A leading : enables silent error reporting:
1526
1527 :ab # accept -a and -b in silent mode
1528
1529The input is `"$@"` by default, unless ARGs are passed.
1530
1531 getopts 'ab' myvar # input is from "$@"
1532 getopts 'xy:z' myvar -x foo # input is --x foo
1533
1534On each iteration, variables are set
1535
1536- The flag character is stored in `VARNAME`.
1537- If the flag has an argument, it's stored in `$OPTARG`.
1538
1539There are two methods of error reporting
1540
1541- Normally, VARNAME is set to `?` and `$OPTARG` is unset.
1542- In silent mode, VARNAME is set to :
1543 - TODO
1544
1545Returns 0 if a flag is parsed, or 1 on end of input or another error.
1546
1547Example:
1548
1549 while getopts "ab:" flag; do
1550 case $flag in
1551 a) flag_a=1 ;;
1552 b) flag_b=$OPTARG" ;;
1553 '?') echo 'Invalid Syntax'; break ;;
1554 esac
1555 done
1556
1557Notes:
1558
1559- `$OPTIND` is initialized to 1 every time a shell starts, and is used to
1560 maintain state between invocations of `getopts`.
1561- The characters `:` and `?` can't be flags.
1562
1563
1564## Conditional
1565
1566### cmd/true
1567
1568Do nothing and return status 0.
1569
1570 if true; then
1571 echo hello
1572 fi
1573
1574### cmd/false
1575
1576Do nothing and return status 1.
1577
1578 if false; then
1579 echo 'not reached'
1580 else
1581 echo hello
1582 fi
1583
1584<h3 id="colon" class="osh-topic">colon :</h3>
1585
1586Like `true`: do nothing and return status 0.
1587
1588## Introspection
1589
1590<h3 id="help" class="osh-topic ysh-topic" oils-embed="1">
1591 help
1592</h3>
1593
1594<!-- pre-formatted for help builtin -->
1595
1596```
1597Usage: help TOPIC?
1598
1599Examples:
1600
1601 help # this help
1602 help echo # help on the 'echo' builtin
1603 help command-sub # help on command sub $(date)
1604
1605 help oils-usage # identical to oils-for-unix --help
1606 help osh-usage # osh --help
1607 help ysh-usage # ysh --help
1608```
1609
1610### hash
1611
1612 hash
1613
1614Display information about remembered commands.
1615
1616 hash FLAG* CMD+
1617
1618Determine the locations of commands using `$PATH`, and remember them.
1619
1620Flag:
1621
1622 -r Discard all remembered locations.
1623<!-- -d Discard the remembered location of each NAME.
1624 -l Display output in a format reusable as input.
1625 -p PATH Inhibit path search, PATH is used as location for NAME.
1626 -t Print the full path of one or more NAME.-->
1627
1628### cmd/type
1629
1630 type FLAG* NAME+
1631
1632Print the type of each NAME, if it were the first word of a command. Is it a
1633shell keyword, builtin command, shell function, alias, or executable file on
1634$PATH?
1635
1636Flags:
1637
1638 -a Show all possible candidates, not just the first one
1639 -f Don't search for shell functions
1640 -P Only search for executable files
1641 -t Print a single word: alias, builtin, file, function, proc, keyword
1642
1643Note: [`invoke --show`][invoke] is more general than `type`.
1644
1645Similar names: [type][]
1646
1647[type]: chap-index.html#type
1648
1649<!-- TODO:
1650- procs are counted as shell functions, should be their own thing
1651- Hay nodes ('hay define x') also live in the first word namespace, and should
1652 be recognized
1653-->
1654
1655Modeled after the [bash `type`
1656builtin](https://www.gnu.org/software/bash/manual/bash.html#index-type).
1657
1658## Word Lookup
1659
1660### invoke
1661
1662The `invoke` builtin allows more control over name lookup than [simple
1663commands][simple-command].
1664
1665[simple-command]: chap-cmd-lang.html#simple-command
1666
1667Usage:
1668
1669 invoke --show NAME* # Show info about EACH name
1670 invoke NAMESPACE_FLAG+ ARG* # Run a single command with this arg array
1671
1672Namespace flags:
1673
1674 --proc Run YSH procs
1675 including invokable obj
1676 --sh-func Run shell functions
1677 --builtin Run builtin commands (of any kind)
1678 eval : POSIX special
1679 cd : normal
1680 sleep: private (Oils)
1681 --extern Run external commands, like /bin/ls
1682
1683Multiple namespace flags may be passed. They are searched in that order:
1684procs, shell functions, builtins, then extern. The first one wins. (This is
1685different than [command-lookup-order][].)
1686
1687[command-lookup-order]: chap-cmd-lang.html#command-lookup-order
1688
1689If the name isn't found, then `invoke` returns status 127.
1690
1691---
1692
1693Run `invoke --show NAME` to see all categories a name is found in.
1694
1695- The `--show` flag respects the [command-lookup-order][]
1696- Shell keywords and aliases are shown, but `invoke` doesn't run them.
1697
1698---
1699
1700Examples:
1701
1702 invoke ls # usage error: no namespace flags
1703
1704 invoke --builtin echo hi # like builtin echo hi
1705 invoke --builtin --extern ls /tmp # like command ls /tmp (no function lookup)
1706
1707 invoke --show true sleep ls # similar to type -a true sleep ls
1708
1709Related:
1710
1711- [builtin][] - like `--builtin`
1712- [command][] - like `--builtin --extern`
1713- [runproc][] - like `--proc --sh-func`
1714- [type][cmd/type] - like `--show`
1715
1716[builtin]: chap-builtin-cmd.html#builtin
1717[command]: chap-builtin-cmd.html#command
1718[runproc]: chap-builtin-cmd.html#runproc
1719[cmd/type]: chap-builtin-cmd.html#cmd/type
1720[command-lookup-order]: chap-cmd-lang.html#command-lookup-order
1721
1722### runproc
1723
1724Runs a named proc with the given arguments. It's often useful as the only top
1725level statement in a "task file":
1726
1727 proc p {
1728 echo hi
1729 }
1730 runproc @ARGV
1731
1732Like 'builtin' and 'command', it affects the lookup of the first word.
1733
1734### command
1735
1736 command FLAG* CMD ARG*
1737
1738Look up CMD as a shell builtin or executable file, and execute it with the
1739given ARGs.
1740
1741Flags:
1742
1743 -v Instead of executing CMD, print a description of it.
1744<!-- -p Use a default value for PATH that is guaranteed to find all of the
1745 standard utilities.
1746 -V Print a more verbose description of CMD.-->
1747
1748Note: [`invoke --show`][invoke] is more general than `command -v`.
1749
1750[invoke]: chap-builtin-cmd.html#invoke
1751
1752### builtin
1753
1754 builtin CMD ARG*
1755
1756Look up CMD as a shell builtin, and execute it with the given ARGs.
1757
1758## Interactive
1759
1760### alias
1761
1762 alias NAME=CODE
1763
1764Make NAME a shortcut for executing CODE, e.g. `alias hi='echo hello'`.
1765
1766 alias NAME
1767
1768Show the value of this alias.
1769
1770 alias
1771
1772Show a list of all aliases.
1773
1774Tips:
1775
1776Prefer shell functions like:
1777
1778 ls() {
1779 command ls --color "$@"
1780 }
1781
1782to aliases like:
1783
1784 alias ls='ls --color'
1785
1786Functions are less likely to cause parsing problems.
1787
1788- Quoting like `\ls` or `'ls'` disables alias expansion
1789- To remove an existing alias, use [unalias](chap-builtin-cmd.html#unalias).
1790
1791### unalias
1792
1793 unalias NAME
1794
1795Remove the alias NAME.
1796
1797<!--Flag:
1798
1799 -a Removes all existing aliases.-->
1800
1801### history
1802
1803 history FLAG*
1804
1805Display and manipulate the shell's history entries.
1806
1807 history NUM
1808
1809Show the last NUM history entries.
1810
1811Flags:
1812
1813 -c Clears the history.
1814 -d POS Deletes the history entry at position POS.
1815<!-- -a
1816 -n
1817 -r
1818 -w
1819 -p
1820 -s -->
1821
1822### fc
1823
1824 fc FLAG* FIRST? LAST?
1825
1826"Fix a command" from the shell's history.
1827
1828`fc -l` displays commands. FIRST and LAST specify a range of command numbers,
1829where:
1830
1831- A positive number is an index into the history list.
1832- A negative number is an offset from the current command.
1833- If FIRST is omitted, the value `-16` is used.
1834- If LAST is omitted, the current command is used.
1835
1836Flags:
1837
1838 -l List commands (rather than editing)
1839 -n Omit line numbers
1840 -r Use reverse order (newest first)
1841
1842<!--
1843Not implemented
1844
1845-e EDITOR
1846-s
1847-->
1848
1849## Unsupported
1850
1851### enable
1852
1853Bash has this, but OSH won't implement it.
1854