This document covers scripts and custom commands in Cosmos Shell.
- Spaces/tabs separate tokens; newlines end statements (or use
;) #starts a comment to end of line
- Allowed: letters, digits,
_,-,.,\,$ - Keywords (case-insensitive):
if,while,for,do,loop,def,return,break,continue
- Form:
$name(letters/digits/underscore) - Script args:
$0= path,$1,$2... = positional arguments - Assign:
$name = <expression>
- Integers:
42,314 - Negatives:
-1
| Type | Syntax | Notes |
|---|---|---|
| Single-quoted | 'text' |
Literal, no escapes. Double ' for quote: 'it''s' |
| Double-quoted | "text $name" |
Literal $; escapes: \n, \r, \t, \\, \", \uXXXX |
| Interpolated | $"Hello $name" |
Variable and expression substitution with $var and $(...) |
Interpolation is enabled only by the explicit $"..." prefix. Use $(...) for expressions, for example $"Total: $($foo + $bar)". The complete contents must form an expression, and command expressions are not allowed inside an interpolated string. Within an interpolated string, escape a literal dollar sign as \$. In ordinary double-quoted strings, $name and $(...) remain literal text and are never evaluated.
Access piped JSON with dot notation:
$.values[0].id # property and array access| Type | Example |
|---|---|
| String | 'text' or "literal $var" |
| Number | 42, 3.14 |
| Boolean | true, false |
| Variable | $name |
| JSON | { id: "1" }, [1,2,3] |
| Category | Operators |
|---|---|
| Arithmetic | + - * / % ** |
| Comparison | < <= > >= == != |
| Logical | && || ^ ! |
| Grouping | ( ... ) |
| Assignment | = += -= *= /= |
$name = "value" # assign
echo $name # use
echo $"Hello $name" # interpolate
echo "Hello $name" # print $name literallyThe shell provides three built-in session variables:
| Variable | Description |
|---|---|
$sessionRequestCharge |
Read-only cumulative request charge observed during the current connection. |
$sessionChargedOperationCount |
Read-only number of command operations that reported a positive charge. |
$sessionRequestChargeWarningThreshold |
Configurable warning threshold in RUs. A positive value enables the warning; 0 disables it. |
For example, $sessionRequestChargeWarningThreshold = 100 prints one warning when the
current connection reaches or exceeds 100 observed RUs. The warning is emitted
only once for that threshold. A successful connect resets the accumulated
charge and operation count and rearms the warning, while preserving the
configured maximum. Assigning a different positive maximum also rearms the
warning for the new threshold.
For script positional parameters, see Writing and Running Scripts.
Cosmos Shell scripts are plain text files, usually with a .csh extension. A script contains the same statements you can type in the interactive shell: commands, assignments, pipes, loops, functions, and exec.
Example script:
# seed.csh
connect $1
cd $2/$3
query "SELECT * FROM c"Run a script by using the script path as the command name and placing script arguments after it:
seed.csh "AccountEndpoint=...;AccountKey=..." mydb mycontainerInside the script, positional parameters are available as variables:
| Variable | Value |
|---|---|
$0 |
Script path used to start the script |
$1 |
First script argument |
$2 |
Second script argument |
$3... |
Additional script arguments |
Script arguments are evaluated by the caller before the script starts. Use quotes for values with spaces, semicolons, or shell-significant characters such as connection strings.
Use -c to run a command or script and exit:
cosmosdbshell -c "seed.csh \"AccountEndpoint=...;AccountKey=...\" mydb mycontainer"Use -k to run a command or script and then stay in the interactive shell:
cosmosdbshell -k "seed.csh \"AccountEndpoint=...;AccountKey=...\" mydb mycontainer"Startup connection options still belong to the shell process, not to the script. Because everything after -c / -k is captured as the command, place app-level options before -c / -k:
cosmosdbshell --connect "AccountEndpoint=...;AccountKey=..." -c "seed.csh mydb mycontainer"Quotes around the command are optional — the shell joins all remaining tokens after -c / -k into a single command string:
cosmosdbshell --connect "AccountEndpoint=...;AccountKey=..." -c seed.csh mydb mycontainerIf you want a value such as --connect to be passed to the script, put it inside the -c or -k command text (after -c everything goes to the script anyway):
cosmosdbshell -c "seed.csh --connect xyz"When standard input is redirected, the shell reads it as command text. This is useful for running inline scripts:
echo "connect \"AccountEndpoint=...;AccountKey=...\"; ls" | cosmosdbshellTo run a script file with parameters through piped input, pipe a script invocation:
echo "seed.csh \"AccountEndpoint=...;AccountKey=...\" mydb mycontainer" | cosmosdbshellPiping the contents of a script file directly runs those statements as standard input, so there is no script filename and no positional parameter list for that input stream. Use -c, -k, or pipe a script invocation when you need $0, $1, $2, and later parameters.
Each script run gets its own variable scope. Variables from the caller are readable at script start, but assignments inside the script stay local to that script run and do not leak back to the caller.
if $n > 0 { echo "positive" } else { echo "non-positive" }$i = 0
while $i < 3 { echo $i; $i = $i + 1 }for $x in ["a","b","c"] { echo $x }Commands can be used as expressions (for loops, assignments, and parenthesized expressions). This is useful for iterating over command results.
# Iterate local files
for $file in (dir "*.csh") { echo $file.name }
# Capture a command result
$dbs = (ls)
echo $dbsThe exec statement evaluates an expression to get a command name or a script path, then executes it with optional arguments.
exec <expression> [arg1] [arg2] ...Notes:
- If the evaluated value is a file path that exists, the shell runs it as a
.cshscript. - Argument parsing stops at
;, newline,}, or|(so you can chain with pipes).
Examples:
$script = {path: "myscript.csh", name: "My Script"}
exec $script.path arg1 arg2
for $file in (dir "examples/list_dir/*.csh") { exec $file.path }
$cmd = "ls"
exec $cmd -m 5do { echo "tick" } while $conditionloop {
if $done { break }
echo "running"
}while $true {
if $skip { continue }
if $done { break }
}Define reusable commands invoked like built-ins.
def name [param1 param2] { <statements> }def greet [who] { echo $"Hello $who" }
greet "Cosmos"- Arguments available as
$param1,$param2inside body - Functions have own variable scope (don't leak to caller)
- Globals remain readable
def add [a b] { return ($a + $b) }
add 2 3 | echo $"sum=$."returnstops execution and sets result- Returned JSON can be accessed with paths downstream
- Without
return, function completes with last state
def range3 { return [1,2,3] }
range3 | for $n in $. { echo $"n=$n" }def ensure_container [db container pk] {
mkdb $db
cd $db
mkcon $container $pk
cd $container
}
def seed [count] {
for $i in [1,2,3,4,5] {
echo $"[{\"id\":\"item$i\",\"pk\":\"$i\",\"value\":$i}]" | mkitem
}
}
connect $1
ensure_container sampledb items /pk
seed 5.prop # property access
.values[0] # array index
$.values[0].id # from piped JSONChain with pipes:
query "SELECT * FROM c" | $.[0] | .idGroup statements with { ... }. Separate by newline or ;.
{ echo "a"; echo "b" }| passes result from left to right command:
query "SELECT * FROM c" | echo $.values[0]
echo '[{"id":"a"}]' | mkitem- Use
defto encapsulate repeatable sequences - Return JSON from functions for pipeline consumption
- Use
$"..."interpolation when composing JSON formkitem - Prefer
returnwhen producing values for downstream commands