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

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