Commands
| this is a command | curl -s https://syshell.org/ |
use "" to pass arguments with spaces or other special
characters |
mkdir "New Folder" |
commands can span multiple lines, if indented. No need for
backslashes. Comment with # |
|
Commands vs. Expressions Syntax
To determine whether it is a call or an expression, parser checks the leftmost symbols:
- it's an expression, if:
- otherwise, it's a command
This rules are consistent for standalone calls, calls done inside the assign operator, or calls done inside parens:
| standalone call | call in assign | inline call |
|---|---|---|
put 1 |
$one := put 1 |
print (put 1) |
/bin/echo 1 |
$one := /bin/echo 1 |
print (/bin/echo 1) |
~/bin/go version |
$vsn := ~/bin/go version |
print (~/bin/go version) |
./script.sy |
$res := ./script.sy |
print (./script.sy) |
| standalone expr | expr in assign | inline expr |
|---|---|---|
| N/A | $two := 1 + 1 |
print (1 + 1) |
| N/A | $map := {a: 1} + {b: 2} |
print ({a: 1} + {b: 2}) |
| N/A | $list := [1] + [2, 3] |
print ([1] + [2, 3]) |
| N/A | $two := (put 10)/5 |
print ((put 10)/5) |
| N/A | $msg := "Hi " + "there" |
print ("hi " + "there") |
| N/A | $msg := 'Hi ' + 'there' |
print ('hi ' + 'there') |
| N/A | $three := $one + $two |
print ($one + $two) |
A few command start with a digit (e.g. 7z or
9p), in this case use run syntax with quoted
command name:
| extract a 7z archive | |
| run a command, stored in a variable | |
| execute a command based on extension | |
Argument Syntax
There are two types of arguments:
- bareword is usually a plain string, e.g.
mv file.jpg file.jpeghas two barewords:file.jpgandfile.jpeg. - primary expression is an expression without binary
and unary operations, e.g.
mv $op.from $op.dsthas two primary expressions, both are variables with a key accessor..
Similarly to commands vs. expressions, to distinguish barewords vs. primary parser checks the left most symbols:
- it's a primary expression, if:
- otherwise, it's a bareword.
time Modifier
time executes a provided command and reports execution statistics:
realtime taken to execute the command.userCPUis how much CPU time was spent by the command, it can be bigger thanreal, if command used multiple CPUs.systemCPUis how much CPU time was spend by the OS kernel.execsis how many external programs were started.
time outputs a map with this fields to the output
stream:
>> time sleep 1
{ real: 1.008347:s, userCPU: 2.724:ms, systemCPU: 3.652:ms, execs: 1 }
This output can be captured in a standard assignment:
>> $a, $b, $time := time put 1 2
>> print A=$a B=$b time=$time
A=1 B=2 time={ real: 21.32:µs, userCPU: 0:s, systemCPU: 0:s, execs: 0 }
>> put $time.real
21.32:µs
ignore Modifier
ignore executes a provided command,
while redirecting error stream to /dev/null and silencing
all errors.
$lines... := ignore cat maybe-exists.txt
$lines will be [], if file doesn't exist,
otherwise it will contain a list of its lines.
mute Modifier
mute executes a provided command, while
redirecting both output and error streams to /dev/null:
mute apt update
It does not, however, silence errors: in the example above, if
apt update exits with non-zero exit code, it will cause a
panic.
try Modifier
try executes a provided command, captures its error or exit code, and appends to the output stream after the command output:
$lines..., $err := try cat counter.txt
if $err != null {
print 0 > counter.txt
$lines = ["0"]
}
It's guaranteed that, if no error occurred or if an external program
exited with 0 exit code, the captured error will be null. try is
experimental and most likely will be revised.
wrap and defer
Instead of running a command immediately, it's possible to 'box' or
'wrap' and run this command later when necessary or when the current
function exits. Check out wrap and defer for that.
Grammar
<commandMode>
= <command> # first symbols must comply with rules above
| run <command>
| defer <command>
| wrap <command>
<command>
= <commandName> <args>*
| time <command>
| ignore <command>
| mute <command>
| try <command>