OILS / doc / ref / chap-builtin-cmd.md View on Github | oilshell.org

1346 lines, 852 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
46Pretty prints interpreter state. Some of these are implementation details,
47subject to change.
48
49Examples:
50
51 pp proc # print all procs and their doc comments
52
53 var x = :| one two |
54 pp cell x # dump the "guts" of a cell, which is a location for a value
55
56 pp asdl (x) # dump the ASDL "guts"
57
58 pp line (x) # single-line stable format, for spec tests
59
60## Handle Errors
61
62### error
63
64The `error` builtin interrupts shell execution.
65
66If there's a surrounding `try` block, the `_error` register is set, and
67execution proceeds after the block.
68
69Otherwise, the shell exits with a non-zero status.
70
71Examples:
72
73 error 'Missing /tmp' # program fails with status 10
74
75 try {
76 error 'Another problem'
77 }
78 echo $[error.code] # => 10
79
80Override the default error code of `10` with a named argument:
81
82 error 'Missing /tmp' (code=99) # program fails with status 99
83
84Named arguments add arbitrary properties to the resulting `_error` register:
85
86 error 'Oops' (path='foo.json')
87
88See [YSH Error Handling](../ysh-error-handling.html) for more examples.
89
90### failed
91
92A shortcut for `(_error.code !== 0)`:
93
94 try {
95 ls /tmp
96 }
97 if failed {
98 echo 'ls failed'
99 }
100
101It saves you 7 punctuation characters: `( _ . !== )`
102
103See [YSH Error Handling](../ysh-error-handling.html) for more examples.
104
105### try
106
107Run a block of code, stopping at the first error. (This is implemented with
108`shopt --set errexit`)
109
110`try` sets the `_error` register to a dict, and always returns 0.
111
112 try {
113 ls /nonexistent
114 }
115 if (_error.code !== 0) {
116 echo 'ls failed'
117 }
118
119Handle expression errors:
120
121 try {
122 var x = 42 / 0
123 }
124
125And errors from compound commands:
126
127 try {
128 ls | wc -l
129 diff <(sort left.txt) <(sort right.txt)
130 }
131
132The case statement can be useful:
133
134 try {
135 grep PATTERN FILE.txt
136 }
137 case (_error.code) {
138 (0) { echo 'found' }
139 (1) { echo 'not found' }
140 (else) { echo "grep returned status $[_error.code]" }
141 }
142
143See [YSH Error Handling](../ysh-error-handling.html) for more examples.
144
145### boolstatus
146
147Runs a command, and requires the exit code to be 0 or 1.
148
149 if boolstatus egrep '[0-9]+' myfile { # e.g. aborts on status 2
150 echo 'found' # status 0 means found
151 } else {
152 echo 'not found' # status 1 means not found
153 }
154
155It's meant for external commands that "return" more than 2 values, like true /
156false / fail, rather than pass / fail.
157
158### assert
159
160Evaluates and expression, and fails if it is not truthy.
161
162 assert (false) # fails
163 assert [false] # also fails (the expression is evaluated)
164
165It's common to pass an unevaluated expression with `===`:
166
167 func f() { return (42) }
168
169 assert [43 === f()]
170
171In this special case, you get a nicer error message:
172
173> Expected: 43
174> Got: 42
175
176That is, the left-hand side should be the expected value, and the right-hand
177side should be the actual value.
178
179## Shell State
180
181### ysh-cd
182
183It takes a block:
184
185 cd / {
186 echo $PWD
187 }
188
189### ysh-shopt
190
191It takes a block:
192
193 shopt --unset errexit {
194 false
195 echo 'ok'
196 }
197
198### shvar
199
200Execute a block with a global variable set.
201
202 shvar IFS=/ {
203 echo "ifs is $IFS"
204 }
205 echo "ifs restored to $IFS"
206
207### ctx
208
209Execute a block with a shared "context" that can be updated using the `ctx`
210built-in.
211
212 var mydict = {}
213 ctx push (mydict) {
214 # = mydict => {}
215 ctx set (mykey='myval')
216 }
217 # = mydict => { mykey: 'myval' }
218
219The context can be modified with `ctx set (key=val)`, which updates or inserts
220the value at the given key.
221
222The context can also be updated with `ctx emit field (value)`.
223
224 ctx push (mydict) {
225 # = mydict => {}
226 ctx emit mylist (0)
227 # = mydict => { mylist: [0] }
228 ctx emit mylist (1)
229 }
230 # = mydict => { mylist: [0, 1] }
231
232Contexts can be nested, resulting in a stack of contexts.
233
234 ctx push (mydict1) {
235 ctx set (dict=1)
236 ctx push (mydict2) {
237 ctx set (dict=2)
238 }
239 }
240 # = mydict1 => { dict: 1 }
241 # = mydict2 => { dict: 2 }
242
243`ctx` is useful for creating DSLs, such as a mini-parseArgs.
244
245 proc parser (; place ; ; block_def) {
246 var p = {}
247 ctx push (p, block_def)
248 call place->setValue(p)
249 }
250
251 proc flag (short_name, long_name; type; help) {
252 ctx emit flag ({short_name, long_name, type, help})
253 }
254
255 proc arg (name) {
256 ctx emit arg ({name})
257 }
258
259 parser (&spec) {
260 flag -t --tsv (Bool, help='Output as TSV')
261 flag -r --recursive (Bool, help='Recurse into the given directory')
262 flag -N --count (Int, help='Process no more than N files')
263 arg path
264 }
265
266### push-registers
267
268Save global registers like $? on a stack. It's useful for preventing plugins
269from interfering with user code. Example:
270
271 status_42 # returns 42 and sets $?
272 push-registers { # push a new frame
273 status_43 # top of stack changed here
274 echo done
275 } # stack popped
276 echo $? # 42, read from new top-of-stack
277
278Current list of registers:
279
280 Regex data underlying BASH_REMATCH, _group(), _start(), _end()
281 $?
282 _error # set by the try builtin
283 PIPESTATUS # aka _pipeline_status
284 _process_sub_status
285
286
287## Modules
288
289### runproc
290
291Runs a named proc with the given arguments. It's often useful as the only top
292level statement in a "task file":
293
294 proc p {
295 echo hi
296 }
297 runproc @ARGV
298
299Like 'builtin' and 'command', it affects the lookup of the first word.
300
301### module
302
303Registers a name in the global module dict. Returns 0 if it doesn't exist, or
3041 if it does.
305
306Use it like this in executable files:
307
308 module main || return 0
309
310And like this in libraries:
311
312 module myfile.ysh || return 0
313
314### is-main
315
316The `is-main` builtin returns 1 (false) if the current file was executed with
317the `source` builtin.
318
319In the "main" file, including `-c` or `stdin` input, it returns 0 (true).
320
321Use it like this:
322
323 if is-main {
324 runproc @ARGV
325 }
326
327### use
328
329TODO
330
331Reuse code from other files, respecting namespaces.
332
333 use lib/foo.ysh # relative import, i.ie implicit $_this_dir?
334 # makes name 'foo' available
335
336Bind a specific name:
337
338 use lib/foo.ysh (&myvar) # makes 'myvar' available
339
340Bind multiple names:
341
342 use lib/foo.ysh (&myvar) {
343 var log, die
344 }
345
346Maybe:
347
348 use lib/foo.ysh (&myvar) {
349 var mylog = myvar.log
350 }
351
352Also a declaration
353
354 use --extern grep sed
355
356## I/O
357
358### ysh-read
359
360YSH adds long flags to shell's `read`:
361
362 read --all # whole file including trailing \n, fills $_reply
363 read --all (&x) # fills $x
364
365 read --num-bytes 3 # read N bytes, fills _reply
366 read --num-bytes 3 (&x) # fills $x
367
368 read --raw-line # unbuffered read of line, omitting trailing \n
369 read --raw-line (&x) # fills $x
370
371 read --raw-line --with-eol # include the trailing \n
372
373And a convenience:
374
375 read -0 # read until NUL, synonym for read -r -d ''
376
377You may want to use `fromJson8()` or `fromJson()` after reading a line.
378
379<!--
380
381TODO:
382
383- read --netstr
384- fromJ8Line() is different than from Json8! It's like @()
385
386-->
387
388<!--
389
390Problem with read --json -- there's also https://jsonlines.org, which allows
391
392 {"my": "line"}
393
394That can be done with
395
396 while read --line {
397 var record = fromJson(_reply)
398 }
399
400This is distinct from:
401
402 while read --line --j8 {
403 echo $_reply
404 }
405
406This allows unquoted. Maybe it should be read --j8-line
407
408What about write? These would be the same:
409
410 write --json -- $s
411 write --j8 -- $s
412
413 write -- $[toJson(s)]
414 write -- $[toJson8(s)]
415
416 write --json -- @strs
417 write --j8 -- @strs
418
419 write -- @[toJson(s) for s in strs]
420 write -- @[toJson8(s) for s in strs]
421
422It's an argument for getting rid --json and --j8? I already implemented them,
423but it makes the API smaller.
424
425I guess the main thing would be to AVOID quoting sometimes?
426
427 $ write --j8 -- unquoted
428 unquoted
429
430 $ write --j8 -- $'\'' '"'
431 "'"
432 "\""
433
434I think this could be the shell style?
435
436 $ write --shell-str -- foo bar baz
437
438Or it could be
439
440 $ write -- @[toShellString(s) for s in strs]
441
442I want this to be "J8 Lines", but it can be done in pure YSH. It's not built
443into the interpreter.
444
445 foo/bar
446 "hi"
447b'hi'
448u'hi'
449
450But what about
451
452 Fool's Gold
453a'hi' # This feels like an error?
454a"hi" # what about this?
455
456Technically we CAN read those as literal strings
457-->
458
459### ysh-echo
460
461Print arguments to stdout, separated by a space.
462
463 ysh$ echo hi there
464 hi there
465
466The [simple_echo][] option means that flags aren't accepted, and `--` is not
467accepted.
468
469 ysh$ echo -n
470 -n
471
472See the [YSH FAQ][echo-en] for details.
473
474[simple_echo]: chap-option.html#ysh:all
475[echo-en]: ../ysh-faq.html#how-do-i-write-the-equivalent-of-echo-e-or-echo-n
476
477### write
478
479write fixes problems with shell's `echo` builtin.
480
481The default separator is a newline, and the default terminator is a
482newline.
483
484Examples:
485
486 write -- ale bean # write two lines
487
488 write -n -- ale bean # synonym for --end '', like echo -n
489 write --sep '' --end '' -- a b # write 2 bytes
490 write --sep $'\t' --end $'\n' -- a b # TSV line
491
492You may want to use `toJson8()` or `toJson()` before writing:
493
494 write -- $[toJson8(mystr)]
495 write -- $[toJson(mystr)]
496
497
498<!--
499 write --json -- ale bean # JSON encode, guarantees two lines
500 write --j8 -- ale bean # J8 encode, guarantees two lines
501-->
502
503
504### fork
505
506Run a command, but don't wait for it to finish.
507
508 fork { sleep 1 }
509 wait -n
510
511In YSH, use `fork` rather than shell's `&` ([ampersand][]).
512
513[ampersand]: chap-cmd-lang.html#ampersand
514
515### forkwait
516
517The preferred alternative to shell's `()`. Prefer `cd` with a block if possible.
518
519 forkwait {
520 not_mutated=zzz
521 }
522 echo $not_mutated
523
524### fopen
525
526Runs a block passed to it. It's designed so redirects have a **prefix**
527syntax:
528
529 fopen >out.txt {
530 echo 1
531 echo 2
532 }
533
534Rather than shell style:
535
536 { echo 1
537 echo 2
538 } >out.txt
539
540When a block is long, the former is more readable.
541
542## Hay Config
543
544### hay
545
546### haynode
547
548
549## Data Formats
550
551### json
552
553Write JSON:
554
555 var d = {name: 'bob', age: 42}
556 json write (d) # default indentation of 2
557 json write (d, space=0) # no indentation
558
559Read JSON:
560
561 echo hi | json read # fills $_reply by default
562
563Or use an explicit place:
564
565 var x = ''
566 json read (&x) < myfile.txt
567
568Related: [err-json-encode][] and [err-json-decode][]
569
570[err-json-encode]: chap-errors.html#err-json-encode
571[err-json-decode]: chap-errors.html#err-json-decode
572
573### json8
574
575Like `json`, but on the encoding side:
576
577- Falls back to `b'\yff'` instead of lossy Unicode replacement char
578
579On decoding side:
580
581- Understands `b'' u''` strings
582
583Related: [err-json8-encode]() and [err-json8-decode]()
584
585[err-json8-encode]: chap-errors.html#err-json8-encode
586[err-json8-decode]: chap-errors.html#err-json8-decode
587
588## Testing
589
590TODO: describe
591
592## External Lang
593
594TODO: when
595
596
597## I/O
598
599These builtins take input and output. They're often used with redirects.
600
601### read
602
603 read FLAG* VAR*
604
605Read a line from stdin, split it into tokens with the `$IFS` algorithm,
606and assign the tokens to the given variables. When no VARs are given,
607assign to `$REPLY`.
608
609Note: When writing ySH, prefer the extensions documented in
610[ysh-read](#ysh-read). The `read` builtin is confusing because `-r` needs to
611be explicitly enabled.
612
613Flags:
614
615 -a ARRAY assign the tokens to elements of this array
616 -d CHAR use DELIM as delimiter, instead of newline
617 -n NUM read up to NUM characters, respecting delimiters
618 -p STR print the string PROMPT before reading input
619 -r raw mode: don't let backslashes escape characters
620 -s silent: do not echo input coming from a terminal
621 -t NUM time out and fail after TIME seconds
622 -t 0 returns whether any input is available
623 -u FD read from file descriptor FD instead of 0 (stdin)
624
625 <!-- -N NUM read up to NUM characters, ignoring delimiters -->
626 <!-- -e use readline to obtain the line
627 -i STR use STR as the initial text for readline -->
628
629### echo
630
631 echo FLAG* ARG*
632
633Prints ARGs to stdout, separated by a space, and terminated by a newline.
634
635Flags:
636
637 -e enable interpretation of backslash escapes
638 -n omit the trailing newline
639<!-- -E -->
640
641See [char-escapes](chap-mini-lang.html#char-escapes).
642
643### printf
644
645 printf FLAG* FMT ARG*
646
647Formats values and prints them. The FMT string contain three types of objects:
648
6491. Literal Characters
6502. Character escapes like `\t`. See [char-escapes](chap-mini-lang.html#char-escapes).
6513. Percent codes like `%s` that specify how to format each each ARG.
652
653If not enough ARGS are passed, the empty string is used. If too many are
654passed, the FMT string will be "recycled".
655
656Flags:
657
658 -v VAR Write output in variable VAR instead of standard output.
659
660Format specifiers:
661
662 %% Prints a single "%".
663 %b Interprets backslash escapes while printing.
664 %q Prints the argument escaping the characters needed to make it reusable
665 as shell input.
666 %d Print as signed decimal number.
667 %i Same as %d.
668 %o Print as unsigned octal number.
669 %u Print as unsigned decimal number.
670 %x Print as unsigned hexadecimal number with lower-case hex-digits (a-f).
671 %X Same as %x, but with upper-case hex-digits (A-F).
672 %f Print as floating point number.
673 %e Print as a double number, in "±e" format (lower-case e).
674 %E Same as %e, but with an upper-case E.
675 %g Interprets the argument as double, but prints it like %f or %e.
676 %G Same as %g, but print it like %E.
677 %c Print as a single char, only the first character is printed.
678 %s Print as string
679 %n The number of characters printed so far is stored in the variable named
680 in the argument.
681 %a Interprets the argument as double, and prints it like a C99 hexadecimal
682 floating-point literal.
683 %A Same as %a, but print it like %E.
684 %(FORMAT)T Prints date and time, according to FORMAT as a format string
685 for strftime(3). The argument is the number of seconds since
686 epoch. It can also be -1 (current time, also the default value
687 if there is no argument) or -2 (shell startup time).
688
689### readarray
690
691Alias for `mapfile`.
692
693### mapfile
694
695 mapfile FLAG* ARRAY?
696
697Reads lines from stdin into the variable named ARRAY (default
698`${MAPFILE[@]}`).
699
700Flags:
701
702 -t Remove the trailing newline from every line
703<!--
704 -d CHAR use CHAR as delimiter, instead of the default newline
705 -n NUM copy up to NUM lines
706 -O NUM begins copying lines at the NUM element of the array
707 -s NUM discard the first NUM lines
708 -u FD read from FD file descriptor instead of the standard input
709 -C CMD run CMD every NUM lines specified in -c
710 -c NUM every NUM lines, the CMD command in C will be run
711-->
712
713## Run Code
714
715These builtins accept shell code and run it.
716
717### source
718
719 source SCRIPT ARG*
720
721Execute SCRIPT with the given ARGs, in the context of the current shell. That is,
722existing variables will be modified.
723
724---
725
726Oils extension: If the SCRIPT starts with `///`, we look for scripts embedded in
727the `oils-for-unix` binary. Example:
728
729 source ///osh/two.sh # load embedded script
730
731 : ${LIB_OSH=fallback/dir}
732 source $LIB_OSH/two.sh # same thing
733
734The [LIB_OSH][] form is useful for writing a script that works under both bash
735and OSH.
736
737- Related: the [cat-em][] tool prints embedded scripts.
738
739[LIB_OSH]: chap-special-var.html#LIB_OSH
740[cat-em]: chap-front-end.html#cat-em
741
742
743### eval
744
745 eval ARG+
746
747Creates a string by joining ARGs with a space, then runs it as a shell command.
748
749Example:
750
751 # Create the string echo "hello $name" and run it.
752 a='echo'
753 b='"hello $name"'
754 eval $a $b
755
756Tips:
757
758- Using `eval` can confuse code and user-supplied data, leading to [security
759issues][].
760- Prefer passing single string ARG to `eval`.
761
762[security issues]: https://mywiki.wooledge.org/BashFAQ/048
763
764YSH eval:
765
766 var myblock = ^(echo hi)
767 eval (myblock) # => hi
768
769
770### trap
771
772 trap FLAG* CMD SIGNAL*
773
774Registers the shell string CMD to be run after the SIGNALs are received. If
775the CMD is empty, then the signal is ignored.
776
777Flags:
778
779 -l Lists all signals and their signal number
780 -p Prints a list of the installed signal handlers
781
782Tip:
783
784Prefer passing the name of a shell function to `trap`.
785
786## Set Options
787
788The `set` and `shopt` builtins set global shell options. YSH code should use
789the more natural `shopt`.
790
791### set
792
793 set FLAG* ARG*
794
795Sets global shell options. Short style:
796
797 set -e
798
799Long style:
800
801 set -o errexit
802
803Set the arguments array:
804
805 set -- 1 2 3
806
807### shopt
808
809 shopt FLAG* OPTION* BLOCK?
810
811Sets global shell options.
812
813Flags:
814
815 -s --set Turn the named options on
816 -u --unset Turn the named options off
817 -p Print option values
818 -o Use older set of options, normally controlled by 'set -o'
819 -q Return 0 if the option is true, else 1
820
821Examples:
822
823 shopt --set errexit
824
825You can set or unset multiple options with the groups `strict:all`,
826`ysh:upgrade`, and `ysh:all`.
827
828If a block is passed, then the mutated options are pushed onto a stack, the
829block is executed, and then options are restored to their original state.
830
831## Working Dir
832
833These 5 builtins deal with the working directory of the shell.
834
835### cd
836
837 cd FLAG* DIR
838
839Changes the working directory of the current shell process to DIR.
840
841If DIR isn't specified, change to `$HOME`. If DIR is `-`, change to `$OLDPWD`
842(a variable that the sets to the previous working directory.)
843
844Flags:
845
846 -L Follow symbolic links, i.e. change to the TARGET of the symlink.
847 (default).
848 -P Don't follow symbolic links.
849
850### pwd
851
852 pwd FLAG*
853
854Prints the current working directory.
855
856Flags:
857
858 -L Follow symbolic links if present (default)
859 -P Don't follow symbolic links. Print the link instead of the target.
860
861### pushd
862
863<!--pushd FLAGS DIR-->
864 pushd DIR
865<!--pushd +/-NUM-->
866
867Add DIR to the directory stack, then change the working directory to DIR.
868Typically used with `popd` and `dirs`.
869
870<!--FLAGS:
871 -n Don't change the working directory, just manipulate the stack
872NUM:
873 Rotates the stack the number of places specified. Eg, given the stack
874 '/foo /bar /baz', where '/foo' is the top of the stack, pushd +1 will move
875 it to the bottom, '/bar /baz /foo'-->
876
877### popd
878
879 popd
880
881Removes a directory from the directory stack, and changes the working directory
882to it. Typically used with `pushd` and `dirs`.
883
884### dirs
885
886 dirs FLAG*
887
888Shows the contents of the directory stack. Typically used with `pushd` and
889`popd`.
890
891Flags:
892
893 -c Clear the dir stack.
894 -l Show the dir stack, but with the real path instead of ~.
895 -p Show the dir stack, but formatted as one line per entry.
896 -v Like -p, but numbering each line.
897
898## Completion
899
900These builtins implement our bash-compatible autocompletion system.
901
902### complete
903
904Registers completion policies for different commands.
905
906### compgen
907
908Generates completion candidates inside a user-defined completion function.
909
910It can also be used in scripts, i.e. outside a completion function.
911
912### compopt
913
914Changes completion options inside a user-defined completion function.
915
916### compadjust
917
918Adjusts `COMP_ARGV` according to specified delimiters, and optionally set
919variables cur, prev, words (an array), and cword. May also set 'split'.
920
921This is an OSH extension that makes it easier to run the bash-completion
922project.
923
924### compexport
925
926Complete an entire shell command string. For example,
927
928 compexport -c 'echo $H'
929
930will complete variables like `$HOME`. And
931
932 compexport -c 'ha'
933
934will complete builtins like `hay`, as well as external commands.
935
936
937## Shell Process
938
939These builtins mutate the state of the shell process.
940
941### exec
942
943 exec BIN_PATH ARG*
944
945Replaces the running shell with the binary specified, which is passed ARGs.
946BIN_PATH must exist on the file system; i.e. it can't be a shell builtin or
947function.
948
949### umask
950
951 umask MODE?
952
953Sets the bit mask that determines the permissions for new files and
954directories. The mask is subtracted from 666 for files and 777 for
955directories.
956
957Oils currently supports writing masks in octal.
958
959If no MODE, show the current mask.
960
961### ulimit
962
963 ulimit --all
964 ulimit -a
965 ulimit FLAGS* -RESOURCE_FLAG VALUE?
966
967 ulimit FLAGS* VALUE? # discouraged
968
969Show and modify process resource limits.
970
971Flags:
972
973 -S for soft limit
974 -H for hard limit
975
976 -c -d -f ... # ulimit --all shows all resource flags
977
978Show a table of resources:
979
980 ulimit --all
981 ulimit -a
982
983For example, the table shows that `-n` is the flag that controls the number
984file descriptors, the soft and hard limit for `-n`, and the multiplication
985"factor" for the integer VALUE you pass.
986
987---
988
989Here are examples of using resource flags.
990
991Get the soft limit for the number of file descriptors:
992
993 ulimit -S -n
994 ulimit -n # same thing
995
996Get the hard limit:
997
998 ulimit -H -n
999
1000Set the soft or hard limit:
1001
1002 ulimit -S -n 100
1003 ulimit -H -n 100
1004
1005Set both limits:
1006
1007 ulimit -n 100
1008
1009A special case that's discouraged: with no resource flag, `-f` is assumed:
1010
1011 ulimit # equivalent to ulimit -f
1012 ulimit 100 # equivalent to ulimit -f 100
1013
1014### times
1015
1016 times
1017
1018Shows the user and system time used by the shell and its child processes.
1019
1020## Child Process
1021
1022### jobs
1023
1024 jobs
1025
1026Shows all jobs running in the shell and their status.
1027
1028### wait
1029
1030 wait FLAG* ARG
1031
1032Wait for processes to exit.
1033
1034If the ARG is a PID, wait only for that job, and return its status.
1035
1036If there's no ARG, wait for all child processes.
1037
1038<!--
1039The ARG can be a PID (tracked by the kernel), or a job number (tracked by the
1040shell). Specify jobs with the syntax `%jobnumber`.
1041-->
1042
1043Flags:
1044
1045 -n Wait for the next process to exit, rather than a specific process.
1046
1047Wait can be interrupted by a signal, in which case the exit code indicates the
1048signal number.
1049
1050### fg
1051
1052 fg JOB?
1053
1054Returns a job running in the background to the foreground. If no JOB is
1055specified, use the latest job.
1056
1057<!--<h4 id="bg">bg</h4>
1058
1059The bg builtin resumes suspend job, while keeping it in the background.
1060
1061bg JOB?
1062
1063JOB:
1064 Job ID to be resumed in the background. If none is specified, the latest job
1065 is chosen. -->
1066
1067## External
1068
1069### test
1070
1071 test OP ARG
1072 test ARG OP ARG
1073 [ OP ARG ] # [ is an alias for test that requires closing ]
1074 [ ARG OP ARG ]
1075
1076Evaluates a conditional expression and returns 0 (true) or 1 (false).
1077
1078Note that [ is the name of a builtin, not an operator in the language. Use
1079'test' to avoid this confusion.
1080
1081String expressions:
1082
1083 -n STR True if STR is not empty.
1084 'test STR' is usually equivalent, but discouraged.
1085 -z STR True if STR is empty.
1086 STR1 = STR2 True if the strings are equal.
1087 STR1 != STR2 True if the strings are not equal.
1088 STR1 < STR2 True if STR1 sorts before STR2 lexicographically.
1089 STR1 > STR2 True if STR1 sorts after STR2 lexicographically.
1090 Note: < and > should be quoted like \< and \>
1091
1092File expressions:
1093
1094 -a FILE Synonym for -e.
1095 -b FILE True if FILE is a block special file.
1096 -c FILE True if FILE is a character special file.
1097 -d FILE True if FILE is a directory.
1098 -e FILE True if FILE exists.
1099 -f FILE True if FILE is a regular file.
1100 -g FILE True if FILE has the sgid bit set.
1101 -G FILE True if current user's group is also FILE's group.
1102 -h FILE True if FILE is a symbolic link.
1103 -L FILE True if FILE is a symbolic link.
1104 -k FILE True if FILE has the sticky bit set.
1105 -O FILE True if current user is the file owner.
1106 -p FILE True if FILE is a named pipe (FIFO).
1107 -r FILE True if FILE is readable.
1108 -s FILE True if FILE has size bigger than 0.
1109 -S FILE True if FILE is a socket file.
1110 -t FD True if file descriptor FD is open and refers to a terminal.
1111 -u FILE True if FILE has suid bit set.
1112 -w FILE True if FILE is writable.
1113 -x FILE True if FILE is executable.
1114 FILE1 -nt FILE2 True if FILE1 is newer than FILE2 (mtime).
1115 FILE1 -ot FILE2 True if FILE1 is older than FILE2 (mtime).
1116 FILE1 -ef FILE2 True if FILE1 is a hard link to FILE2.
1117<!-- -N FILE True if FILE was modified since last read (mtime newer than atime).-->
1118
1119Arithmetic expressions coerce arguments to integers, then compare:
1120
1121 INT1 -eq INT2 True if they're equal.
1122 INT1 -ne INT2 True if they're not equal.
1123 INT1 -lt INT2 True if INT1 is less than INT2.
1124 INT1 -le INT2 True if INT1 is less or equal than INT2.
1125 INT1 -gt INT2 True if INT1 is greater than INT2.
1126 INT1 -ge INT2 True if INT1 is greater or equal than INT2.
1127
1128Other expressions:
1129
1130 -o OPTION True if the shell option OPTION is set.
1131 -v VAR True if the variable VAR is set.
1132
1133The test builtin also supports POSIX conditionals like -a, -o, !, and ( ), but
1134these are discouraged.
1135
1136<!-- -R VAR True if the variable VAR has been set and is a nameref variable. -->
1137
1138Oils supports these long flags:
1139
1140 --dir same as -d
1141 --exists same as -e
1142 --file same as -f
1143 --symlink same as -L
1144
1145### getopts
1146
1147 getopts SPEC VAR ARG*
1148
1149A single iteration of flag parsing. The SPEC is a sequence of flag characters,
1150with a trailing `:` to indicate that the flag takes an argument:
1151
1152 ab # accept -a and -b
1153 xy:z # accept -x, -y arg, and -z
1154
1155The input is `"$@"` by default, unless ARGs are passed.
1156
1157On each iteration, the flag character is stored in VAR. If the flag has an
1158argument, it's stored in `$OPTARG`. When an error occurs, VAR is set to `?`
1159and `$OPTARG` is unset.
1160
1161Returns 0 if a flag is parsed, or 1 on end of input or another error.
1162
1163Example:
1164
1165 while getopts "ab:" flag; do
1166 case $flag in
1167 a) flag_a=1 ;;
1168 b) flag_b=$OPTARG" ;;
1169 '?') echo 'Invalid Syntax'; break ;;
1170 esac
1171 done
1172
1173Notes:
1174- `$OPTIND` is initialized to 1 every time a shell starts, and is used to
1175 maintain state between invocations of `getopts`.
1176- The characters `:` and `?` can't be flags.
1177
1178### kill
1179
1180Unimplemented.
1181
1182<!-- Note: 'kill' accepts job control syntax -->
1183
1184## Introspection
1185
1186<h3 id="help" class="osh-topic ysh-topic" oils-embed="1">
1187 help
1188</h3>
1189
1190<!-- pre-formatted for help builtin -->
1191
1192```
1193Usage: help TOPIC?
1194
1195Examples:
1196
1197 help # this help
1198 help echo # help on the 'echo' builtin
1199 help command-sub # help on command sub $(date)
1200
1201 help oils-usage # identical to oils-for-unix --help
1202 help osh-usage # osh --help
1203 help ysh-usage # ysh --help
1204```
1205
1206### hash
1207
1208 hash
1209
1210Display information about remembered commands.
1211
1212 hash FLAG* CMD+
1213
1214Determine the locations of commands using `$PATH`, and remember them.
1215
1216Flag:
1217
1218 -r Discard all remembered locations.
1219<!-- -d Discard the remembered location of each NAME.
1220 -l Display output in a format reusable as input.
1221 -p PATH Inhibit path search, PATH is used as location for NAME.
1222 -t Print the full path of one or more NAME.-->
1223
1224### cmd/type
1225
1226 type FLAG* NAME+
1227
1228Print the type of each NAME, if it were the first word of a command. Is it a
1229shell keyword, builtin command, shell function, alias, or executable file on
1230$PATH?
1231
1232Flags:
1233
1234 -a Show all possible candidates, not just the first one
1235 -f Don't search for shell functions
1236 -P Only search for executable files
1237 -t Print a single word: alias, builtin, file, function, or keyword
1238
1239Similar names: [type][]
1240
1241[type]: chap-index.html#type
1242
1243<!-- TODO:
1244- procs are counted as shell functions, should be their own thing
1245- Hay nodes ('hay define x') also live in the first word namespace, and should
1246 be recognized
1247-->
1248
1249Modeled after the [bash `type`
1250builtin](https://www.gnu.org/software/bash/manual/bash.html#index-type).
1251
1252## Word Lookup
1253
1254### command
1255
1256 command FLAG* CMD ARG*
1257
1258Look up CMD as a shell builtin or executable file, and execute it with the
1259given ARGs. That is, the lookup ignores shell functions named CMD.
1260
1261Flags:
1262
1263 -v Instead of executing CMD, print a description of it.
1264 Similar to the 'type' builtin.
1265<!-- -p Use a default value for PATH that is guaranteed to find all of the
1266 standard utilities.
1267 -V Print a more verbose description of CMD.-->
1268
1269### builtin
1270
1271 builtin CMD ARG*
1272
1273Look up CMD as a shell builtin, and execute it with the given ARGs. That is,
1274the lookup ignores shell functions and executables named CMD.
1275
1276## Interactive
1277
1278### alias
1279
1280 alias NAME=CODE
1281
1282Make NAME a shortcut for executing CODE, e.g. `alias hi='echo hello'`.
1283
1284 alias NAME
1285
1286Show the value of this alias.
1287
1288 alias
1289
1290Show a list of all aliases.
1291
1292Tips:
1293
1294Prefer shell functions like:
1295
1296 ls() {
1297 command ls --color "$@"
1298 }
1299
1300to aliases like:
1301
1302 alias ls='ls --color'
1303
1304Functions are less likely to cause parsing problems.
1305
1306- Quoting like `\ls` or `'ls'` disables alias expansion
1307- To remove an existing alias, use [unalias](chap-builtin-cmd.html#unalias).
1308
1309### unalias
1310
1311 unalias NAME
1312
1313Remove the alias NAME.
1314
1315<!--Flag:
1316
1317 -a Removes all existing aliases.-->
1318
1319### history
1320
1321 history FLAG*
1322
1323Display and manipulate the shell's history entries.
1324
1325 history NUM
1326
1327Show the last NUM history entries.
1328
1329Flags:
1330
1331 -c Clears the history.
1332 -d POS Deletes the history entry at position POS.
1333<!-- -a
1334 -n
1335 -r
1336 -w
1337 -p
1338 -s -->
1339
1340
1341## Unsupported
1342
1343### enable
1344
1345Bash has this, but OSH won't implement it.
1346