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