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

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