rc-shell: document if-not pitfall, stderr redirect, fn body syntax

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Levi Neely 2026-04-20 20:31:46 +02:00
parent 2dd6fea2e6
commit 742716dcec
1 changed files with 34 additions and 7 deletions

View File

@ -34,9 +34,6 @@ result=`split{command} # split using 'split' instead of $ifs
if(test -f file) {
echo exists
}
if not { # separate statement, new line
echo missing
}
for(i in 1 2 3) { echo $i }
for(i) { echo $i } # iterates over $* if no list
@ -51,24 +48,53 @@ case *
}
```
**`if not` is unreliable** — though documented in the rc manual, `if not` causes syntax errors in practice. Use a flag variable instead:
```
ok=0
if(test -f file) { echo exists; ok=1 }
if(~ $ok 0) echo missing
```
Chained `if` statements serve as logical AND:
```
if(test -f file) if(~ $mode rw) echo writable
```
## Functions & Pattern Matching
```
fn name { echo $* $1 } # define (all args, first arg)
fn name { # always use multi-line bodies
echo $* $1 # $* all args, $1 first arg
}
fn name # remove definition
~ $file *.txt # pattern match (sets $status)
if(~ $#list 0) { echo empty }
```
**Single-line function bodies with `;` cause syntax errors.** Always use multi-line:
```
# WRONG: fn die { echo $* >[1=2]; exit 1 }
fn die {
echo $* >[1=2]
exit 1
}
```
## Redirection & Pipes
```
>out >>out <in <<EOF # stdout, append, stdin, here doc
>[2]err >[2=1] >[2=] # fd 2 to file, fd 2 to fd 1, close fd 2
>[2]err >[2=] # fd 2 to file, close fd 2
>[1=2] # stdout to stderr (write to stderr)
>[2=1] # stderr to stdout
<[0=3] # fd 0 from fd 3
<{cmd} >{cmd} <>{cmd} # process substitution
cmd1 | cmd2 # pipe
|[2] |[1=2] # pipe fd 2, pipe fd 2 to fd 1
{ cmd1; cmd2 } > file # redirect block stdout to file
```
## Operators
@ -88,10 +114,11 @@ cmd1 | cmd2 # pipe
- Backticks `{cmd}`, not `$(cmd)`
- Lists `(a b c)`, 1-indexed
- `if not` on new line
- No reliable `if/else`: use flag variable + chained `if` instead of `if not`
- `test` or `~`, not `[[ ]]`
- `$#var` not `${#var}`, `$"var` not `"$*"`
- `>[2=1]` not `2>&1`
- `>[1=2]` to write to stderr (stdout→stderr), `>[2=1]` for stderr→stdout
- `>[2]file` redirects fd 2 to a file; bare `>[2]` (no filename) is a syntax error
- No `${var:-default}`
- `fn name` not `function name`
- Single quotes only (double quotes not special)