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

1783 lines, 1139 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][]
661
662[rewrite_extern]: chap-option.html#rewrite_extern
663
664### rm
665
666`rm` is a *private* builtin that removes files.
667
668 rm FLAG* FILE*
669
670Flags:
671
672 -f Don't fail if the file exist, and don't fail if no arguments are
673 passed.
674
675Return 0 on success, and non-zero otherwise.
676
677- Related: [rewrite_extern][]
678
679### sleep
680
681`sleep` is a *private* builtin that puts the shell process to sleep for the
682given number of seconds.
683
684Example:
685
686 builtin sleep 0.1 # wait 100 milliseconds
687
688It respects signals:
689
690- `SIGINT` / Ctrl-C cancels the command, with the standard behavior:
691 - in an interactive shell, you return to the prompt
692 - a non-interactive shell is cancelled
693- Upon receiving other signals, Oils run pending traps, and then continues to
694 sleep.
695
696It's compatible with the POSIX `sleep` utility:
697
698 sleep 2 # wait 2 seconds
699
700## Hay Config
701
702### hay
703
704### haynode
705
706
707## Data Formats
708
709### json
710
711Write JSON:
712
713 var d = {name: 'bob', age: 42}
714 json write (d) # default indent of 2, type errors
715 json write (d, space=0) # no indent
716 json write (d, type_errors=false) # non-serializable types become null
717 # (e.g. Obj, Proc, Eggex)
718
719Read JSON:
720
721 echo hi | json read # fills $_reply by default
722
723Or use an explicit place:
724
725 var x = ''
726 json read (&x) < myfile.txt
727
728Related: [err-json-encode][] and [err-json-decode][]
729
730[err-json-encode]: chap-errors.html#err-json-encode
731[err-json-decode]: chap-errors.html#err-json-decode
732
733### json8
734
735Like `json`, but on the encoding side:
736
737- Falls back to `b'\yff'` instead of lossy Unicode replacement char
738
739On decoding side:
740
741- Understands `b'' u''` strings
742
743Related: [err-json8-encode]() and [err-json8-decode]()
744
745[err-json8-encode]: chap-errors.html#err-json8-encode
746[err-json8-decode]: chap-errors.html#err-json8-decode
747
748## I/O
749
750These builtins take input and output. They're often used with redirects.
751
752### read
753
754 read FLAG* VAR*
755
756Read input from `stdin`, and assign pieces of input to variables. Without
757flags, `read` uses this algorithm:
758
7591. Read bytes from `stdin`, one at a time, until a newline `\n`.
760 - Respect `\` escapes and line continuations.
761 - Any NUL bytes are removed from the input.
7621. Use the `$IFS` algorithm to split the line into N pieces, where `N` is the
763 number of `VAR` specified. Each piece is assigned to the corresponding
764 variable.
765 - If no VARs are given, assign to the `$REPLY` var.
766
767The `-r` flag is useful to disable backslash escapes.
768
769POSIX mandates the slow behavior of reading one byte at a time. In YSH, you
770can avoid this by using [io.stdin][], or a `--long-flag` documented in
771[ysh-read](#ysh-read).
772
773Flags:
774
775 -a ARRAY assign the tokens to elements of this array
776 -d CHAR use DELIM as delimiter, instead of newline
777 -n NUM read up to NUM characters, respecting delimiters. When -r is not
778 specified, backslash escape of the form "\?" is counted as one
779 character. This is the Bash behavior, but other shells such as
780 ash and mksh count the number of bytes with "-n" without
781 considering backslash escaping.
782 -p STR print the string PROMPT before reading input
783 -r raw mode: don't let backslashes escape characters
784 -s silent: do not echo input coming from a terminal
785 -t NUM time out and fail after TIME seconds
786 -t 0 returns whether any input is available
787 -u FD read from file descriptor FD instead of 0 (stdin)
788
789 <!-- -N NUM read up to NUM characters, ignoring delimiters -->
790 <!-- -e use readline to obtain the line
791 -i STR use STR as the initial text for readline -->
792
793Performance summary: [YSH Input/Output > Three Types of I/O][ysh-io-three]
794
795### echo
796
797 echo FLAG* ARG*
798
799Prints ARGs to stdout, separated by a space, and terminated by a newline.
800
801Flags:
802
803 -e enable interpretation of backslash escapes
804 -n omit the trailing newline
805<!-- -E -->
806
807`echo` in YSH does **not** accept these flags. See [ysh-echo](#ysh-echo) and
808[the FAQ entry][echo-en]. (This is unusual because YSH doesn't usually "break"
809OSH.)
810
811See [char-escapes](chap-mini-lang.html#char-escapes) to see what's supported
812when `-e` is passed.
813
814### printf
815
816 printf FLAG* FMT ARG*
817
818Formats values and prints them. The FMT string contain three types of objects:
819
8201. Literal Characters
8212. Character escapes like `\t`. See [char-escapes](chap-mini-lang.html#char-escapes).
8223. Percent codes like `%s` that specify how to format each each ARG.
823
824If not enough ARGS are passed, the empty string is used. If too many are
825passed, the FMT string will be "recycled".
826
827Flags:
828
829 -v VAR Write output in variable VAR instead of standard output.
830
831Format specifiers:
832
833 %% Prints a single "%".
834 %b Interprets backslash escapes while printing.
835 %q Prints the argument escaping the characters needed to make it reusable
836 as shell input.
837 %d Print as signed decimal number.
838 %i Same as %d.
839 %o Print as unsigned octal number.
840 %u Print as unsigned decimal number.
841 %x Print as unsigned hexadecimal number with lower-case hex-digits (a-f).
842 %X Same as %x, but with upper-case hex-digits (A-F).
843 %f Print as floating point number.
844 %e Print as a double number, in "±e" format (lower-case e).
845 %E Same as %e, but with an upper-case E.
846 %g Interprets the argument as double, but prints it like %f or %e.
847 %G Same as %g, but print it like %E.
848 %c Print as a single char, only the first character is printed.
849 %s Print as string
850 %n The number of characters printed so far is stored in the variable named
851 in the argument.
852 %a Interprets the argument as double, and prints it like a C99 hexadecimal
853 floating-point literal.
854 %A Same as %a, but print it like %E.
855 %(FORMAT)T Prints date and time, according to FORMAT as a format string
856 for strftime(3). The argument is the number of seconds since
857 epoch. It can also be -1 (current time, also the default value
858 if there is no argument) or -2 (shell startup time).
859
860### readarray
861
862Alias for `mapfile`.
863
864### mapfile
865
866 mapfile FLAG* ARRAY?
867
868Reads lines from stdin into the variable named ARRAY (default
869`${MAPFILE[@]}`).
870
871Flags:
872
873 -t Remove the trailing newline from every line
874<!--
875 -d CHAR use CHAR as delimiter, instead of the default newline
876 -n NUM copy up to NUM lines
877 -O NUM begins copying lines at the NUM element of the array
878 -s NUM discard the first NUM lines
879 -u FD read from FD file descriptor instead of the standard input
880 -C CMD run CMD every NUM lines specified in -c
881 -c NUM every NUM lines, the CMD command in C will be run
882-->
883
884## Run Code
885
886These builtins accept shell code and run it.
887
888### source
889
890 source SCRIPT ARG*
891
892Execute SCRIPT with the given ARGs, in the context of the current shell. That is,
893existing variables will be modified.
894
895---
896
897Oils extension: If the SCRIPT starts with `///`, we look for scripts embedded in
898the `oils-for-unix` binary. Example:
899
900 source ///osh/two.sh # load embedded script
901
902 : ${LIB_OSH=fallback/dir}
903 source $LIB_OSH/two.sh # same thing
904
905The [LIB_OSH][] form is useful for writing a script that works under both bash
906and OSH.
907
908- Related: the [cat-em][] tool prints embedded scripts.
909
910[LIB_OSH]: chap-special-var.html#LIB_OSH
911[cat-em]: chap-front-end.html#cat-em
912
913
914### cmd/eval
915
916 eval ARG+
917
918Creates a string by joining ARGs with a space, then runs it as a shell command.
919
920Example:
921
922 # Create the string echo "hello $name" and run it.
923 a='echo'
924 b='"hello $name"'
925 eval $a $b
926
927Tips:
928
929- Using `eval` can confuse code and user-supplied data, leading to [security
930issues][].
931- Prefer passing single string ARG to `eval`.
932
933[security issues]: https://mywiki.wooledge.org/BashFAQ/048
934
935### trap
936
937The `trap` builtin lets you run shell code when events happen. Events are
938signals or interpreter hooks.
939
940 trap -l # List all events and their number
941 trap -p # Print the current trap state: events and handlers
942 trap CMD EVENT* # Register handlers
943 trap - EVENT* # Remove handlers
944
945Examples:
946
947 trap 'echo hi' EXIT INT # Register
948 trap - EXIT INT # Remove
949
950OSH also support legacy syntax, which is not recommended:
951
952 trap 'echo hi' 0 # 0 is the exit trap
953 trap INT # remove signal handler
954 trap 0 # remove exit trap
955 trap 0 INT # remove both
956
957<!--
958 trap '' EVENT* # TODO Ignore events
959-->
960
961Tips:
962
963- Prefer passing the name of a shell function to `trap`.
964 - See [ysh-trap](#ysh-trap) for even nicer idioms.
965- See [Chapter: Plugins and Hooks > Traps](chap-plugin.html#Traps) for a list of
966traps, like `trap '' EXIT`.
967
968### ysh-trap
969
970The `trap` builtin lets you run shell code when events happen.
971
972YSH improves the syntax of the trap builtin, and removes legacy.
973
974 trap -l # List all events and their number
975 trap -p # Print the current trap state: events and handlers
976 trap --add EVENT* BLOCK # Register handlers
977 trap --remove EVENT* # Remove handlers
978
979Examples:
980
981 trap --add EXIT INT {
982 echo 'either exit'
983 echo 'or int'
984 }
985
986 trap --remove EXIT INT
987
988Note: the block argument to `trap --add` doesn't capture variables -- it's not
989a closure. So YSH behaves like OSH, but the syntax doesn't encourage putting
990source code in strings.
991
992## Set Options
993
994The `set` and `shopt` builtins set global shell options. YSH code should use
995the more natural `shopt`.
996
997### set
998
999 set FLAG* ARG*
1000
1001Sets global shell options. Short style:
1002
1003 set -e
1004
1005Long style:
1006
1007 set -o errexit
1008
1009Set the arguments array:
1010
1011 set -- 1 2 3
1012
1013See [Chapter: Global Shell Options](chap-option.html) for a list of options.
1014
1015### shopt
1016
1017 shopt FLAG* OPTION* BLOCK?
1018
1019Sets global shell options.
1020
1021Flags:
1022
1023 -s --set Turn the named options on
1024 -u --unset Turn the named options off
1025 -p Print option values, and 1 if any option is unset
1026 -o Use older set of options, normally controlled by 'set -o'
1027 -q Return 0 if the option is true, else 1
1028
1029This command is compatible with `shopt` in bash. See [ysh-shopt](#ysh-shopt) for
1030details on YSH enhancements.
1031
1032See [Chapter: Global Shell Options](chap-option.html) for a list of options.
1033
1034## Working Dir
1035
1036These 5 builtins deal with the working directory of the shell.
1037
1038### cd
1039
1040 cd FLAG* DIR
1041
1042Changes the working directory of the current shell process to DIR.
1043
1044If DIR isn't specified, change to `$HOME`. If DIR is `-`, change to `$OLDPWD`
1045(a variable that the sets to the previous working directory.)
1046
1047Flags:
1048
1049 -L Follow symbolic links, i.e. change to the TARGET of the symlink.
1050 (default).
1051 -P Don't follow symbolic links.
1052
1053### chdir
1054
1055`chdir` is a synonym for `cd`. Shells like `busybox ash` support it, so OSH
1056does too.
1057
1058### pwd
1059
1060 pwd FLAG*
1061
1062Prints the current working directory.
1063
1064Flags:
1065
1066 -L Follow symbolic links if present (default)
1067 -P Don't follow symbolic links. Print the link instead of the target.
1068
1069### pushd
1070
1071<!--pushd FLAGS DIR-->
1072 pushd DIR
1073<!--pushd +/-NUM-->
1074
1075Add DIR to the directory stack, then change the working directory to DIR.
1076Typically used with `popd` and `dirs`.
1077
1078<!--FLAGS:
1079 -n Don't change the working directory, just manipulate the stack
1080NUM:
1081 Rotates the stack the number of places specified. Eg, given the stack
1082 '/foo /bar /baz', where '/foo' is the top of the stack, pushd +1 will move
1083 it to the bottom, '/bar /baz /foo'-->
1084
1085### popd
1086
1087 popd
1088
1089Removes a directory from the directory stack, and changes the working directory
1090to it. Typically used with `pushd` and `dirs`.
1091
1092### dirs
1093
1094 dirs FLAG*
1095
1096Shows the contents of the directory stack. Typically used with `pushd` and
1097`popd`.
1098
1099Flags:
1100
1101 -c Clear the dir stack.
1102 -l Show the dir stack, but with the real path instead of ~.
1103 -p Show the dir stack, but formatted as one line per entry.
1104 -v Like -p, but numbering each line.
1105
1106## Completion
1107
1108These builtins implement our bash-compatible autocompletion system.
1109
1110### complete
1111
1112Registers completion policies for different commands.
1113
1114### compgen
1115
1116Generates completion candidates inside a user-defined completion function.
1117
1118It can also be used in scripts, i.e. outside a completion function.
1119
1120### compopt
1121
1122Changes completion options inside a user-defined completion function.
1123
1124### compadjust
1125
1126Adjusts `COMP_ARGV` according to specified delimiters, and optionally set
1127variables cur, prev, words (an array), and cword. May also set 'split'.
1128
1129This is an OSH extension that makes it easier to run the bash-completion
1130project.
1131
1132### compexport
1133
1134Complete an entire shell command string. For example,
1135
1136 compexport -c 'echo $H'
1137
1138will complete variables like `$HOME`. And
1139
1140 compexport -c 'ha'
1141
1142will complete builtins like `hay`, as well as external commands.
1143
1144
1145## Shell Process
1146
1147These builtins mutate the state of the shell process.
1148
1149### exec
1150
1151 exec BIN_PATH ARG*
1152
1153Replaces the running shell with the binary specified, which is passed ARGs.
1154BIN_PATH must exist on the file system; i.e. it can't be a shell builtin or
1155function.
1156
1157### umask
1158
1159 umask OCTAL
1160 umask SYMBOLIC[,SYMBOLIC]...
1161
1162 umask FLAG* # print the mask
1163
1164Sets the bit mask that determines the permissions for new files and
1165directories. The mask is subtracted from 666 for files and 777 for
1166directories.
1167
1168If no MODE, show the current mask.
1169
1170Flags:
1171
1172 -p print in a form that may be reused as input
1173 -S print in symbolic form
1174
1175Symbolic mask:
1176
1177 A SYMBOLIC clause is of the form '[ugoa]*([-+=]([rwxXstugo]*))*', the same as is accepted by chmod.
1178
1179 who :: u | g | o | a
1180 operator :: + | - | =
1181 permission :: r | w | x | X | s | t | u | g | o
1182
1183 Who:
1184 ugo set the user, group, or other parts of the file mode bits, respectively
1185 a equivalent to all of ugo
1186
1187 Operator:
1188 + removes specified permission bits from the umask according to who
1189 - adds specified permission bits to the umask according to who
1190 = set all who permissions to 0777, then remove specified permission bits from the umask according to who
1191
1192 Permission:
1193 rwx set the read, write, or execute bit respectively
1194 X set the execute bit iff the umask before this operation has one of its 3 execute bits set
1195 st does nothing, but exists for POSIX compatibility
1196 ugo set permission equal to the umask's u, g, and o bits before this operation
1197
1198Examples:
1199
1200 umask # get the current umask in octal form
1201
1202 umask 0124
1203
1204 umask ug=rwx,o-r # clauses may be joined using commas
1205
1206 umask u+rwx-x-w-r # operators can be chained
1207
1208 umask a=u # [ugo] after the operator represents the initial umask permissions
1209
1210 umask =u # equivalent to `umask a=u`
1211
1212### ulimit
1213
1214 ulimit --all
1215 ulimit -a
1216 ulimit FLAGS* -RESOURCE_FLAG VALUE?
1217
1218 ulimit FLAGS* VALUE? # discouraged
1219
1220Show and modify process resource limits.
1221
1222Flags:
1223
1224 -S for soft limit
1225 -H for hard limit
1226
1227 -c -d -f ... # ulimit --all shows all resource flags
1228
1229Show a table of resources:
1230
1231 ulimit --all
1232 ulimit -a
1233
1234For example, the table shows that `-n` is the flag that controls the number
1235file descriptors, the soft and hard limit for `-n`, and the multiplication
1236"factor" for the integer VALUE you pass.
1237
1238---
1239
1240Here are examples of using resource flags.
1241
1242Get the soft limit for the number of file descriptors:
1243
1244 ulimit -S -n
1245 ulimit -n # same thing
1246
1247Get the hard limit:
1248
1249 ulimit -H -n
1250
1251Set the soft or hard limit:
1252
1253 ulimit -S -n 100
1254 ulimit -H -n 100
1255
1256Set both limits:
1257
1258 ulimit -n 100
1259
1260A special case that's discouraged: with no resource flag, `-f` is assumed:
1261
1262 ulimit # equivalent to ulimit -f
1263 ulimit 100 # equivalent to ulimit -f 100
1264
1265### times
1266
1267 times
1268
1269Shows the user and system time used by the shell and its child processes.
1270
1271## Child Process
1272
1273### jobs
1274
1275 jobs
1276
1277Shows all jobs running in the shell and their status.
1278
1279### wait
1280
1281Wait for jobs to finish, in a few different ways. (A job is a process or a
1282pipeline.)
1283
1284 wait # no arguments
1285
1286Wait for all jobs to terminate. The exit status is 0, unless a signal occurs.
1287
1288 wait -n
1289
1290Wait for the next job to terminate, and return its status.
1291
1292 wait $pid1 $pid2 ...
1293
1294Wait for the jobs specified by PIDs to terminate. Return the status of the
1295last one.
1296
1297 wait %3 %2 ...
1298
1299Wait for the jobs specified by "job specs" to terminate. Return the status of
1300the last one.
1301
1302---
1303
1304If wait is interrupted by a signal, the exit status is the signal number + 128.
1305
1306---
1307
1308When using `set -e` aka `errexit`, `wait --all` is useful. See topic
1309[ysh-wait](#ysh-wait).
1310
1311<!--
1312The ARG can be a PID (tracked by the kernel), or a job number (tracked by the
1313shell). Specify jobs with the syntax `%jobnumber`.
1314-->
1315
1316### ysh-wait
1317
1318YSH extends the `wait` builtin with 2 flags:
1319
1320 wait --all # wait for all jobs, like 'wait'
1321 # but exit 1 if any job exits non-zero
1322
1323 wait --verbose # show a message on each job completion
1324
1325 wait --all --verbose # show a message, and also respect failure
1326
1327### fg
1328
1329 fg JOB?
1330
1331Continues a stopped job in the foreground. This means it can receive signals
1332from the keyboard, like Ctrl-C and Ctrl-Z.
1333
1334If no JOB is specified, use the latest job.
1335
1336### bg
1337
1338UNIMPLEMENTED
1339
1340 bg JOB?
1341
1342Continues a stopped job, while keeping it in the background. This means it
1343**can't** receive signals from the keyboard, like Ctrl-C and Ctrl-Z.
1344
1345If no JOB is specified, use the latest job.
1346
1347### kill
1348
1349The `kill` builtin sends a signal to one or more processes. Usage:
1350
1351 kill (-s SIG | -SIG)? WHAT+ # send SIG to the given processes
1352
1353where
1354
1355 SIG = NAME | NUMBER # e.g. USR1 or 10
1356 WHAT = PID | JOBSPEC # e.g. 789 or %%
1357
1358Examples:
1359
1360 kill -s USR1 789 # send SIGUSR1 to PID 789
1361
1362 kill -s USR1 789 %% # send signal to PID 789 and the current job
1363 kill -s 10 789 %% # specify SIGUSR1 by number instead
1364
1365 kill -USR1 789 %% # shortcut syntax
1366 kill -10 789 %% # shortcut using a number
1367
1368 kill -n USR1 789 %% # -n is a synonym for -s
1369 kill 789 %% # if not specified, the default is SIGTERM
1370
1371---
1372
1373It can also list signals:
1374
1375 kill -L # List all signals
1376 kill -L SIG+ # Translate signals from name to number, and vice versa
1377
1378Examples:
1379
1380 kill -l # List all signals; -l is a synonym for -L
1381 kill -L USR1 USR2 # prints '10 12'
1382 kill -L USR1 15 # prints '10 TERM'
1383
1384## External
1385
1386### test
1387
1388 test OP ARG
1389 test ARG OP ARG
1390 [ OP ARG ] # [ is an alias for test that requires closing ]
1391 [ ARG OP ARG ]
1392
1393Evaluates a conditional expression and returns 0 (true) or 1 (false).
1394
1395Note that `[` is the name of a builtin, not an operator in the language. Use
1396`test` to avoid this confusion.
1397
1398String expressions:
1399
1400 -n STR True if STR is not empty.
1401 'test STR' is usually equivalent, but discouraged.
1402 -z STR True if STR is empty.
1403 STR1 = STR2 True if the strings are equal.
1404 STR1 != STR2 True if the strings are not equal.
1405 STR1 < STR2 True if STR1 sorts before STR2 lexicographically.
1406 STR1 > STR2 True if STR1 sorts after STR2 lexicographically.
1407 Note: < and > should be quoted like \< and \>
1408
1409File expressions:
1410
1411 -a FILE Synonym for -e.
1412 -b FILE True if FILE is a block special file.
1413 -c FILE True if FILE is a character special file.
1414 -d FILE True if FILE is a directory.
1415 -e FILE True if FILE exists.
1416 -f FILE True if FILE is a regular file.
1417 -g FILE True if FILE has the sgid bit set.
1418 -G FILE True if current user's group is also FILE's group.
1419 -h FILE True if FILE is a symbolic link.
1420 -L FILE True if FILE is a symbolic link.
1421 -k FILE True if FILE has the sticky bit set.
1422 -O FILE True if current user is the file owner.
1423 -p FILE True if FILE is a named pipe (FIFO).
1424 -r FILE True if FILE is readable.
1425 -s FILE True if FILE has size bigger than 0.
1426 -S FILE True if FILE is a socket file.
1427 -t FD True if file descriptor FD is open and refers to a terminal.
1428 -u FILE True if FILE has suid bit set.
1429 -w FILE True if FILE is writable.
1430 -x FILE True if FILE is executable.
1431 FILE1 -nt FILE2 True if FILE1 is newer than FILE2 (mtime).
1432 FILE1 -ot FILE2 True if FILE1 is older than FILE2 (mtime).
1433 FILE1 -ef FILE2 True if FILE1 is a hard link to FILE2.
1434<!-- -N FILE True if FILE was modified since last read (mtime newer than atime).-->
1435
1436Arithmetic expressions coerce arguments to integers, then compare:
1437
1438 INT1 -eq INT2 True if they're equal.
1439 INT1 -ne INT2 True if they're not equal.
1440 INT1 -lt INT2 True if INT1 is less than INT2.
1441 INT1 -le INT2 True if INT1 is less or equal than INT2.
1442 INT1 -gt INT2 True if INT1 is greater than INT2.
1443 INT1 -ge INT2 True if INT1 is greater or equal than INT2.
1444
1445Other expressions:
1446
1447 -o OPTION True if the shell option OPTION is set.
1448 -v VAR True if the variable VAR is set.
1449
1450The test builtin also supports POSIX conditionals like -a, -o, !, and ( ), but
1451these are discouraged.
1452
1453<!-- -R VAR True if the variable VAR has been set and is a nameref variable. -->
1454
1455---
1456
1457See [ysh-test](#ysh-test) for log flags like `--file` and `--true`.
1458
1459### getopts
1460
1461 getopts SPEC VAR ARG*
1462
1463A single iteration of flag parsing. The SPEC is a sequence of flag characters,
1464with a trailing `:` to indicate that the flag takes an argument:
1465
1466 ab # accept -a and -b
1467 xy:z # accept -x, -y arg, and -z
1468
1469The input is `"$@"` by default, unless ARGs are passed.
1470
1471On each iteration, the flag character is stored in VAR. If the flag has an
1472argument, it's stored in `$OPTARG`. When an error occurs, VAR is set to `?`
1473and `$OPTARG` is unset.
1474
1475Returns 0 if a flag is parsed, or 1 on end of input or another error.
1476
1477Example:
1478
1479 while getopts "ab:" flag; do
1480 case $flag in
1481 a) flag_a=1 ;;
1482 b) flag_b=$OPTARG" ;;
1483 '?') echo 'Invalid Syntax'; break ;;
1484 esac
1485 done
1486
1487Notes:
1488- `$OPTIND` is initialized to 1 every time a shell starts, and is used to
1489 maintain state between invocations of `getopts`.
1490- The characters `:` and `?` can't be flags.
1491
1492
1493## Conditional
1494
1495### cmd/true
1496
1497Do nothing and return status 0.
1498
1499 if true; then
1500 echo hello
1501 fi
1502
1503### cmd/false
1504
1505Do nothing and return status 1.
1506
1507 if false; then
1508 echo 'not reached'
1509 else
1510 echo hello
1511 fi
1512
1513<h3 id="colon" class="osh-topic">colon :</h3>
1514
1515Like `true`: do nothing and return status 0.
1516
1517## Introspection
1518
1519<h3 id="help" class="osh-topic ysh-topic" oils-embed="1">
1520 help
1521</h3>
1522
1523<!-- pre-formatted for help builtin -->
1524
1525```
1526Usage: help TOPIC?
1527
1528Examples:
1529
1530 help # this help
1531 help echo # help on the 'echo' builtin
1532 help command-sub # help on command sub $(date)
1533
1534 help oils-usage # identical to oils-for-unix --help
1535 help osh-usage # osh --help
1536 help ysh-usage # ysh --help
1537```
1538
1539### hash
1540
1541 hash
1542
1543Display information about remembered commands.
1544
1545 hash FLAG* CMD+
1546
1547Determine the locations of commands using `$PATH`, and remember them.
1548
1549Flag:
1550
1551 -r Discard all remembered locations.
1552<!-- -d Discard the remembered location of each NAME.
1553 -l Display output in a format reusable as input.
1554 -p PATH Inhibit path search, PATH is used as location for NAME.
1555 -t Print the full path of one or more NAME.-->
1556
1557### cmd/type
1558
1559 type FLAG* NAME+
1560
1561Print the type of each NAME, if it were the first word of a command. Is it a
1562shell keyword, builtin command, shell function, alias, or executable file on
1563$PATH?
1564
1565Flags:
1566
1567 -a Show all possible candidates, not just the first one
1568 -f Don't search for shell functions
1569 -P Only search for executable files
1570 -t Print a single word: alias, builtin, file, function, proc, keyword
1571
1572Note: [`invoke --show`][invoke] is more general than `type`.
1573
1574Similar names: [type][]
1575
1576[type]: chap-index.html#type
1577
1578<!-- TODO:
1579- procs are counted as shell functions, should be their own thing
1580- Hay nodes ('hay define x') also live in the first word namespace, and should
1581 be recognized
1582-->
1583
1584Modeled after the [bash `type`
1585builtin](https://www.gnu.org/software/bash/manual/bash.html#index-type).
1586
1587## Word Lookup
1588
1589### invoke
1590
1591The `invoke` builtin allows more control over name lookup than [simple
1592commands][simple-command].
1593
1594[simple-command]: chap-cmd-lang.html#simple-command
1595
1596Usage:
1597
1598 invoke --show NAME* # Show info about EACH name
1599 invoke NAMESPACE_FLAG+ ARG* # Run a single command with this arg array
1600
1601Namespace flags:
1602
1603 --proc Run YSH procs
1604 including invokable obj
1605 --sh-func Run shell functions
1606 --builtin Run builtin commands (of any kind)
1607 eval : POSIX special
1608 cd : normal
1609 sleep: private (Oils)
1610 --extern Run external commands, like /bin/ls
1611
1612Multiple namespace flags may be passed. They are searched in that order:
1613procs, shell functions, builtins, then extern. The first one wins. (This is
1614different than [command-lookup-order][].)
1615
1616[command-lookup-order]: chap-cmd-lang.html#command-lookup-order
1617
1618If the name isn't found, then `invoke` returns status 127.
1619
1620---
1621
1622Run `invoke --show NAME` to see all categories a name is found in.
1623
1624- The `--show` flag respects the [command-lookup-order][]
1625- Shell keywords and aliases are shown, but `invoke` doesn't run them.
1626
1627---
1628
1629Examples:
1630
1631 invoke ls # usage error: no namespace flags
1632
1633 invoke --builtin echo hi # like builtin echo hi
1634 invoke --builtin --extern ls /tmp # like command ls /tmp (no function lookup)
1635
1636 invoke --show true sleep ls # similar to type -a true sleep ls
1637
1638Related:
1639
1640- [builtin][] - like `--builtin`
1641- [command][] - like `--builtin --extern`
1642- [runproc][] - like `--proc --sh-func`
1643- [type][cmd/type] - like `--show`
1644
1645[builtin]: chap-builtin-cmd.html#builtin
1646[command]: chap-builtin-cmd.html#command
1647[runproc]: chap-builtin-cmd.html#runproc
1648[cmd/type]: chap-builtin-cmd.html#cmd/type
1649[command-lookup-order]: chap-cmd-lang.html#command-lookup-order
1650
1651### runproc
1652
1653Runs a named proc with the given arguments. It's often useful as the only top
1654level statement in a "task file":
1655
1656 proc p {
1657 echo hi
1658 }
1659 runproc @ARGV
1660
1661Like 'builtin' and 'command', it affects the lookup of the first word.
1662
1663### command
1664
1665 command FLAG* CMD ARG*
1666
1667Look up CMD as a shell builtin or executable file, and execute it with the
1668given ARGs.
1669
1670Flags:
1671
1672 -v Instead of executing CMD, print a description of it.
1673<!-- -p Use a default value for PATH that is guaranteed to find all of the
1674 standard utilities.
1675 -V Print a more verbose description of CMD.-->
1676
1677Note: [`invoke --show`][invoke] is more general than `command -v`.
1678
1679[invoke]: chap-builtin-cmd.html#invoke
1680
1681### builtin
1682
1683 builtin CMD ARG*
1684
1685Look up CMD as a shell builtin, and execute it with the given ARGs.
1686
1687## Interactive
1688
1689### alias
1690
1691 alias NAME=CODE
1692
1693Make NAME a shortcut for executing CODE, e.g. `alias hi='echo hello'`.
1694
1695 alias NAME
1696
1697Show the value of this alias.
1698
1699 alias
1700
1701Show a list of all aliases.
1702
1703Tips:
1704
1705Prefer shell functions like:
1706
1707 ls() {
1708 command ls --color "$@"
1709 }
1710
1711to aliases like:
1712
1713 alias ls='ls --color'
1714
1715Functions are less likely to cause parsing problems.
1716
1717- Quoting like `\ls` or `'ls'` disables alias expansion
1718- To remove an existing alias, use [unalias](chap-builtin-cmd.html#unalias).
1719
1720### unalias
1721
1722 unalias NAME
1723
1724Remove the alias NAME.
1725
1726<!--Flag:
1727
1728 -a Removes all existing aliases.-->
1729
1730### history
1731
1732 history FLAG*
1733
1734Display and manipulate the shell's history entries.
1735
1736 history NUM
1737
1738Show the last NUM history entries.
1739
1740Flags:
1741
1742 -c Clears the history.
1743 -d POS Deletes the history entry at position POS.
1744<!-- -a
1745 -n
1746 -r
1747 -w
1748 -p
1749 -s -->
1750
1751### fc
1752
1753 fc FLAG* FIRST? LAST?
1754
1755"Fix a command" from the shell's history.
1756
1757`fc -l` displays commands. FIRST and LAST specify a range of command numbers,
1758where:
1759
1760- A positive number is an index into the history list.
1761- A negative number is an offset from the current command.
1762- If FIRST is omitted, the value `-16` is used.
1763- If LAST is omitted, the current command is used.
1764
1765Flags:
1766
1767 -l List commands (rather than editing)
1768 -n Omit line numbers
1769 -r Use reverse order (newest first)
1770
1771<!--
1772Not implemented
1773
1774-e EDITOR
1775-s
1776-->
1777
1778## Unsupported
1779
1780### enable
1781
1782Bash has this, but OSH won't implement it.
1783