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

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