Skip to main content
Version: 0.1.0-alpha.1

Virtual Runtime

The virtual runtime uses Invowk™'s built-in POSIX-compatible shell interpreter (powered by mvdan/sh). It provides consistent shell behavior across all platforms without requiring an external shell.

How It Works​

When you run a command with the virtual runtime, Invowk:

  1. Parses the script using the built-in shell parser
  2. Executes it in an embedded POSIX-like environment
  3. Provides core utilities (echo, test, etc.) built-in

Basic Usage​

{
name: "build"
implementations: [{
script: """
echo "Building..."
go build -o bin/app ./...
echo "Done!"
"""
runtimes: [{name: "virtual"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
}
invowk cmd build --invk-runtime virtual

Cross-Platform Consistency​

The virtual runtime behaves identically on Linux, macOS, and Windows:

{
name: "setup"
implementations: [{
script: """
# This works the same everywhere!
if [ -d "node_modules" ]; then
echo "Dependencies already installed"
else
echo "Installing dependencies..."
npm install
fi
"""
runtimes: [{name: "virtual"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
}

No more "works on my machine" for shell scripts!

Built-in Utilities​

The virtual shell includes core POSIX utilities:

UtilityDescription
echoPrint text
printfFormatted output
test / [Conditionals
true / falseExit with 0/1
pwdPrint working directory
cdChange directory
readRead input
exportSet environment variables

Extended Utilities (u-root)​

When enabled in config (default: true), additional utilities from the u-root library are available:

// In your config file
virtual_shell: {
enable_uroot_utils: true
}

File Operations (7 utilities)​

UtilityDescriptionCommon Flags
catConcatenate and display files-n (number lines)
cpCopy files and directories-r (recursive), -f (force)
lsList directory contents-l (long), -a (all), -R (recursive)
mkdirCreate directories-p (create parents)
mvMove or rename files-f (force), -n (no clobber)
rmRemove files and directories-r (recursive), -f (force)
touchCreate or update file timestamps-c (no create)

Text Processing (8 utilities)​

UtilityDescriptionCommon Flags
headOutput first N lines-n <num> (default 10)
tailOutput last N lines-n <num> (default 10)
wcCount lines, words, bytes-l (lines), -w (words), -c (bytes)
grepSearch for patterns-i (ignore case), -v (invert), -n (line numbers)
sortSort lines-r (reverse), -n (numeric)
uniqFilter adjacent duplicate lines-c (count), -d (duplicates only)
cutSelect portions of lines-d (delimiter), -f (fields)
trTranslate charactersSET1 SET2 (character mapping)
note

These utilities implement POSIX behavior. GNU-specific flags (like --color, --time-style) are silently ignored for compatibility.

Error Identification​

Errors from u-root utilities are prefixed with [uroot] for easy identification:

[uroot] cp: /source/file: no such file or directory
[uroot] rm: /protected: permission denied

No Silent Fallback​

If a u-root command fails, it returns an error immediately. The system does not fall back to host binaries, ensuring bugs are caught rather than masked

POSIX Shell Features​

The virtual shell supports standard POSIX constructs:

Variables​

script: """
NAME="World"
echo "Hello, $NAME!"

# Parameter expansion
echo "${NAME:-default}"
echo "${#NAME}" # Length
"""

Conditionals​

script: """
if [ "$ENV" = "production" ]; then
echo "Production mode"
elif [ "$ENV" = "staging" ]; then
echo "Staging mode"
else
echo "Development mode"
fi
"""

Loops​

script: """
# For loop
for file in *.go; do
echo "Processing $file"
done

# While loop
count=0
while [ $count -lt 5 ]; do
echo "Count: $count"
count=$((count + 1))
done
"""

Functions​

script: """
greet() {
echo "Hello, $1!"
}

greet "World"
greet "Invowk"
"""

Subshells and Command Substitution​

script: """
# Command substitution
current_date=$(date +%Y-%m-%d)
echo "Today is $current_date"

# Subshell
(cd /tmp && echo "In temp: $(pwd)")
echo "Still in: $(pwd)"
"""

Calling External Commands​

The virtual shell can call external commands installed on your system:

script: """
# Calls the real 'go' binary
go version

# Calls the real 'git' binary
git status
"""

External commands are found using the system's PATH.

Environment Variables​

Environment variables work the same as in native:

{
name: "build"
env: {
vars: {
BUILD_MODE: "release"
}
}
implementations: [{
script: """
echo "Building in $BUILD_MODE mode"
go build -ldflags="-s -w" ./...
"""
runtimes: [{name: "virtual"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
}

Flags and Arguments​

Access flags and arguments the same way:

{
name: "greet"
args: [{name: "name", default_value: "World"}]
implementations: [{
script: """
# Using environment variable
echo "Hello, $INVOWK_ARG_NAME!"

# Or positional parameter
echo "Hello, $1!"
"""
runtimes: [{name: "virtual"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
}

Limitations​

No Interpreter Support​

The virtual runtime cannot use non-shell interpreters:

// This will NOT work with virtual runtime!
{
name: "bad-example"
implementations: [{
script: """
#!/usr/bin/env python3
print("This won't work!")
"""
runtimes: [{
name: "virtual"
interpreter: "python3" // ERROR: Not supported
}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
}

For Python, Ruby, or other interpreters, use the native or container runtime.

Bash-Specific Features​

Some bash-specific features are not available:

// These won't work in virtual runtime:
script: """
# Bash arrays (use $@ instead)
declare -a arr=(1 2 3) # Not supported

# Bash-specific parameter expansion
${var^^} # Uppercase - not supported
${var,,} # Lowercase - not supported

# Process substitution
diff <(cmd1) <(cmd2) # Not supported
"""

Stick to POSIX-compatible constructs for virtual runtime.

Dependency Validation​

Dependencies are validated against the virtual shell's capabilities:

{
name: "build"
depends_on: {
tools: [
// These will be checked in the virtual shell environment
{alternatives: ["go"]},
{alternatives: ["git"]}
]
}
implementations: [{
script: "go build ./..."
runtimes: [{name: "virtual"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
}

Advantages​

  • Consistency: Same behavior on Linux, macOS, and Windows
  • No shell dependency: Works even if system shell is unavailable
  • Portability: Scripts work across all platforms
  • Built-in utilities: Core utilities always available
  • Faster startup: No shell process to spawn

When to Use Virtual​

  • Cross-platform scripts: When the same script must work everywhere
  • CI/CD pipelines: Consistent behavior across build agents
  • Simple shell scripts: When you don't need bash-specific features
  • Embedded environments: When external shells aren't available

Configuration​

Configure the virtual shell in your Invowk config file:

// ~/.config/invowk/config.cue (Linux)
// ~/Library/Application Support/invowk/config.cue (macOS)
// %APPDATA%\invowk\config.cue (Windows)

virtual_shell: {
// Enable additional utilities from u-root
enable_uroot_utils: true
}

Next Steps​